Friday 27 October 2017

Winsock Send Data Binary Options


Estoy intentando enviar una estructura a través de un zócalo de UDP del winsock del cliente al servidor, pero no estoy recibiendo los mismos bytes que se han enviado, o por lo menos no ser reassemble la estructura correctamente. La misma cantidad de bytes se reciben como se envían, sin embargo, una vez copiados de nuevo en una nueva estructura en el lado del servidor sólo los dos primeros valores son correctos, y el resto no lo son. En este caso la estructura contiene 1, 2, 52428, 52428 cuando se reciba. ¿Hay algo que he perdido durante el envío / recepción, o es que hacer con la creación de la estructura en el otro extremo En primer lugar, el envío de una estructura en bruto sobre la red es muy no portátil: usted puede tener diferencias de endianness entre remitente y receptor puede alineación hava Diferencias entre el remitente y el receptor Excepto en casos especiales en los que puede estar seguro de que el remitente y el receptor comparten la misma arquitectura, os y compilador, nunca lo haga. La forma normal sería utilizar un formato portátil, ya sea ASCII (robusto pero a menudo subóptimo) o binario, pero debe definir una representación no ambigua. Por ejemplo, al usar 4 uint16t: Pero si tuviera un problema de diferentes arquitecturas, no obtendría los dos primeros valores. Tu problema actual es mucho más simple. En la recepción de código que tiene. Y sizeof (datos) es sizeof (char). Que es de 4 bytes en una máquina de 32 bits mientras que sizeof (Header) es 4 2 8 bytes. Deberías tener en su lugar. Por cierto, usted podría evitar la parte memcpy. Válido ya que el segundo argumento a sendto es un const void y la conversión a void es automática. Ya que el segundo argumento a recv es en realidad un vacío. También puede tener diferencias de relleno o diferencias de tamaño de tipo de datos. Todo esto puede variar dependiendo del hardware, sistema operativo, compilador, versión del compilador, banderas del compilador, opciones del compilador, pragmas circundantes. Por no mencionar el código souce en sí. La única forma segura de utilizar esta técnica es asegurarse de que ambos pares están construidos a partir de los mismos archivos de objeto. Ndash EJP Feb 23 15 at 9:06 Puede utilizar: pragma pack (show) para imprimir la alineación como advertencia y asegurarse de que es la misma. Si hay una diferencia uso pragma pack (n) como este: No tienes que memcpy la estructura de búfer. Usted puede utilizar su objeto de cabecera directamente. Cómo utilizar TCP eficazmente Los recién llegados a la programación de red casi siempre se enfrentan a problemas desde el principio donde parece que la red o la pila de TCP / IP es munging sus datos. Esto generalmente viene como un gran shock, porque el recién llegado se suele decir antes de esto que TCP es un protocolo de transporte de datos confiable. De hecho, TCP y Winsock son bastante confiables si los usa correctamente. Este tutorial discutirá los problemas más comunes que la gente experimenta al aprender a usar TCP. Problema 1: Los paquetes son ilusiones Este problema aparece en varios aspectos: ldquoMi programa cliente envió 100 bytes, pero el programa de servidor sólo tiene 50.rdquo ldquoMi programa cliente envió varios paquetes pequeños, pero el programa del servidor recibió un paquete grande. rdquo ldquoHow can Descubro cuántos bytes están esperando en un socket dado, así que puedo configurar un buffer de recepción para el tamaño del packetrdquo Creo que entender este problema es uno de los ritos TCP / IPrsquos de paso. El concepto central que debe comprender es que TCP es un protocolo de flujo. Esto significa que si envía 100 bytes, el extremo receptor podría recibir los 100 bytes a la vez, o 100 bytes individuales separados, o cuatro fragmentos de 25 bytes. Aún más confuso, el receptor podría recibir ese bloque de 100 bytes más algunos datos del envío anterior y algunos del envío siguiente. Por lo tanto, usted pregunta, ¿cómo puede hacer que un programa reciba paquetes completos sólo El método más fácil es prefijar cada paquete con un valor de longitud. Por ejemplo, puede prefijar cada paquete con un entero sin signo de 2 bytes que indique cuánto tiempo es el paquete. Los prefijos de longitud son más efectivos cuando los datos de cada paquete de protocolo no tienen una estructura particular, como datos binarios en bruto. Vea este ejemplo para el código que lee los paquetes prefixados por longitud desde un flujo TCP. Otro método para configurar paquetes en la parte superior de un protocolo de flujo se denomina ldquodelimiting. rdquo Cada paquete que envía en dicho esquema es seguido por un delimitador único. El truco es pensar en un buen delimitador que debe ser un carácter o cadena de caracteres que nunca se producirá dentro de un paquete. Algunos buenos ejemplos de protocolos delimitados son NNTP, POP3 y SMTP, todos los cuales usan un par de retorno de carro / avance de línea (CRLF) como su delimitador. Delimitar generalmente sólo funciona bien con los protocolos basados ​​en texto, porque por diseño se limitan a un subconjunto de todos los caracteres legales que deja un montón de posibles delimitadores para elegir. Itrsquos también es posible tener un enfoque mixto. HTTP, por ejemplo, tiene encabezados delimitados por CRLF, uno de los cuales puede ser Content-length, que es un prefijo de longitud para los datos que siguen a los encabezados. De estos dos métodos, prefiero el prefijo de longitud, porque la delimitación requiere que su programa lea ciegamente hasta que encuentre el final del paquete, mientras que el prefijo de longitud permite que el programa comience a tratar con el paquete tan pronto como llegue el prefijo de longitud. Por otro lado, los esquemas de delimitación se prestan a la flexibilidad, si se diseña el protocolo como un lenguaje de computadora esto implica que sus analizadores de protocolos será compleja. Hay un par de otras preocupaciones para manejar correctamente paquetes encima de TCP. Primero, siempre compruebe el valor de retorno de recv (). Que indica cuántos bytes que colocó en su buffer mdash que bien puede devolver menos bytes de lo que esperaba. En segundo lugar, donrsquot tratar de mirar en el Winsock stackrsquos buffers para ver si un paquete completo ha llegado. Por varias razones, peeking causa problemas. En su lugar, leer todos los datos directamente en sus buffers applicationrsquos y procesar allí. Problema 2: Byte Ordering Usted ha notado indudablemente todas las llamadas de ntohs () y de htonl () requeridas en la programación de Winsock, pero usted puede ser que no sepa porqué son requeridas. La razón es que hay dos formas comunes de almacenar números enteros en una computadora: big-endian y little-endian. Los números de Big-Endian se almacenan con el byte más significativo en la posición de memoria más baja (primero en primer plano), mientras que los sistemas de little-endian invierten esto. Obviamente, dos ordenadores deben estar de acuerdo en un formato de número común si deben comunicarse, por lo que la especificación TCP / IP define un orden de bytes de ldquonetwork que los encabezados (y por tanto Winsock) usan todos. El resultado final es, si está enviando enteros desnudos como parte de su protocolo de red, y el extremo de recepción está en una plataforma que utiliza una representación entera diferente, percibirá los datos como ilegibles. Para solucionar esto, siga el ejemplo del protocolo TCP y use el orden de bytes de la red, siempre. Los mismos principios se aplican a otros formatos de datos específicos de la plataforma, como los valores de punto flotante. Winsock no define funciones para crear representaciones neutral de plataforma de datos distintos de enteros, pero hay un protocolo denominado Representación de datos externos (XDR) que maneja esto. XDR formaliza una forma independiente de la plataforma para que dos equipos se envíen entre sí varios tipos de datos. XDR es lo suficientemente simple como para poder implementarlo alternativamente, puede echar un vistazo a la página Bibliotecas para encontrar bibliotecas que implementan el protocolo XDR. Por lo que vale la pena, el orden de bytes de la red es grande-endian, aunque usted nunca debe tomar ventaja de este hecho. Algunos programadores que trabajan en máquinas big-endian ignoran los problemas de ordenación de bytes, pero esto hace que su código no sea portátil, y puede convertirse en un mal hábito que te morderá más tarde. Las CPUs más comunes de little-endian son Intel x86 y Digital Alpha. La mayoría de todo lo demás es grande-endian. Hay algunos dispositivos bi-endian que pueden funcionar en cualquiera de los modos, como el PowerPC y el HP PA-RISC 8000. La mayoría de PowerPCs siempre se ejecutan en modo big-endian, sin embargo, y sospecho que lo mismo es cierto para el PA - RISC. Problema 3: Estructura de relleno Para ilustrar el problema de relleno de estructura, considere esta declaración C: Suponiendo 32 bits int s, puede suponer que la estructura ocupa 6 bytes, pero esto no es así. Por razones de eficiencia, las estructuras de almohadillas de compiladores alinean los miembros de datos de una manera que sea conveniente para la CPU. La mayoría de las CPUs pueden acceder a números enteros de 32 bits más rápido si están en direcciones igualmente divisibles por 4, por lo que la estructura anterior probablemente ocupará 12 bytes en estos sistemas. Este problema vuelve a la cabeza cuando intenta enviar una estructura sobre Winsock entero, como esto: A menos que el programa de recepción se compiló en la misma arquitectura de máquina con el mismo compilador y las mismas opciones de compilador, no tiene ninguna garantía de que la otra máquina recibirá Los datos correctamente. La solución es enviar siempre las estructuras ldquopackedrdquo enviando los miembros de datos uno a la vez. Puede obligar a su compilador a empacar las estructuras para usted, con una penalización de velocidad resultante en el código que accede a esas estructuras. Visual C puede hacer esto con la opción de línea de comandos / Zp o la directiva de paquete pragma, y ​​Borland C puede hacer esto con la opción de línea de comandos - a. Sin embargo, tenga en cuenta el problema de ordenación de bytes: si envía una estructura empaquetada en su lugar, asegúrese de reordenar correctamente sus bytes antes de enviarla. La moral de la historia Confíe en Winsock para enviar sus datos correctamente, pero donrsquot asumir que funciona de la manera que usted piensa que debería Copyright copy 1998-2004 por Warren Young. Todos los derechos reservados. Raw socket de programación en Windows con winsock Raw sockets utilizando winsock Raw sockets o Raw Packets, le dan la posibilidad de acceder a todo el contenido de un paquete o datagrama, tanto para la lectura y la escritura. En otras palabras, puede fabricar un paquete entero de acuerdo a sus gustos y disgustos. Por ejemplo, un paquete TCP contendría un encabezado IP, un encabezado TCP y, a continuación, los datos reales que deben transmitirse. Cuando se trabaja con sockets normales, lo que enviamos a un socket es en realidad la parte de datos. En tal escenario, la pila de red OS tiene la responsabilidad de agregar el encabezado con todos los campos establecidos a valores relevantes. Cuando enviamos los datos a un destino, la pila agrega los encabezados y envía el paquete, y cuando recibimos algunos datos, la pila quita los encabezados y entrega los datos a nuestra aplicación. Así que nos salvamos del trabajo de diseñar los encabezados. Para las aplicaciones normales de Internet, no hay necesidad de preocuparse por las operaciones de cabecera, ya que están ahí para la transmisión y recepción seguras de datos, y una vez que la transferencia se ha completado, su necesidad ha terminado y se descargan. Pero la historia no termina ahí, hay algunas personas que necesitan sockets sin procesar. En este artículo, vamos a echar un vistazo a los contenidos de un paquete TCP general, y tratar de hacer un paquete sin procesar y transmitirlo. Lo haremos en Windows XP usando el compilador VC 6.0. Aceptar, así que echemos un vistazo a los encabezados IP y TCP. Los ejemplos que se muestran aquí construirían un paquete tcp sin procesar y lo enviarían a través de la interfaz de red. Winsock tiene soporte de socket raw limitado a través de varias versiones de Windows, como se discute más adelante. Como alternativa, también puede crear zócalos sin procesar en ventanas utilizando la biblioteca winpcap. Encabezados RFC 791 da la estructura de un encabezado IP como: A continuación viene el encabezado TCP para la transmisión utilizando el protocolo TCP. RFC 793 da la estructura. Y al final es sus datos, para comprender la importancia de cada campo, leer el RFC necesario o algún otro buen TCP / IP tutorial en la red, ya que hay mucho. Si tiene conocimientos previos de programación de socket, los encabezados se explican por sí mismos. Ahora, ¿por qué es la característica de socket raw de importancia para la seguridad de la red Bueno, un aspecto importante de la seguridad de la red que necesita esta característica es la exploración. La exploración es de muchos tipos. Primeros pasos y Windows En primer lugar, debe entenderse muy claramente que los sockets no procesados ​​no son una característica de la API de red (aunque debe estar presente Allí como una opción) pero de la pila del protocolo del OS. Para implementar sockets sin procesar, todo lo que tenemos que hacer es informar al sistema operativo que el búfer de paquetes que estamos proporcionando tendrá el encabezado y por lo que el sistema operativo debe transmitirlo como es sin agregar ningún encabezado thats todos, nada más que hacer. El sistema operativo Unix tiene soporte de socket raw desde tiempos antiguos. Pero el problema es con Windows. Ninguno de Windows 95, 98, 98SE admite sockets sin procesar. Los sockets sin procesar se hicieron disponibles en Windows desde Windows 2000 Windows XP continuó esto. Pero de repente, el soporte de socket sin procesar se eliminó de Windows XP a través de un parche en SP2. Vista no lo tiene. Un parche de seguridad llamado MS05-019 (support. microsoft/kb/897656) es lo que desactiva sockets sin procesar en XP SP2 y puede hacer lo mismo para incluso SP1. Probablemente Windows 2003 SP1 también implementa el mismo resultado siendo el final de sockets sin procesar. Un exhaustivo resumen está disponible en seclists. org/nmap-hackers/2005/0005.html. Windows 95, 98, 98SE no admiten sockets sin procesar, pero esto no termina la historia. Si desea que la instalación, entonces la solución es utilizar un controlador de paquetes de terceros como Winpcap. Estos controladores de paquetes harán su tarea independientemente de lo que le gusta y no le gusta al sistema operativo. Windows XP y XP SP1 tienen soporte completo de socket raw y por lo que la vida es fácil. Por lo tanto, si desea realizar raw socketing en Windows, utilice Winpcap o no se sienta desesperado por instalar SP2, o use Windows 2003 que, según mi conocimiento, tiene soporte de socket raw. Technet. microsoft/hi-in/library/bb457156(en-us).aspx debería contar más. Por lo tanto, vamos a resumir: 1. Windows 95, 98, 98SE, NT4.0 sólo primas ICMP e IGMP con características restringidas. 2. Windows 2000, XP, XP SP1, 2003 Soporte completo del zócalo crudo para recibir y enviar propósitos. 3. Windows XP SP2 Sólo se pueden enviar ICMP, IGMP y UDP crudos con dirección de origen adecuada (IP spoofing restricted). Pero, los sockets crudos completos pueden ser recibidos, lo que significa que puede oler todos los datos entrantes y leer sus encabezados. Nota. Winsock Ver. 2.0 Así que si tu sistema no soporta sockets sin procesar, entonces cambia a Linux o usa Winpcap. Hay artículos en este sitio que explican cómo usar winpcap para enviar paquetes sin procesar. Busca por ellos. Código La última línea, setsockopt, indica al sistema operativo que el socket s tendrá el encabezado incluido (IPHDRINCL) en el nivel IP (IPPROTOIP) en el búfer de datos que envía. IPPROTORAW crea un socket absolutamente crudo, y usted tiene que escribir todos los encabezados usted mismo. IPPROTOUDP, IPROTOTCP también están disponibles para los respectivos tipos de paquetes. Ahora, vamos a necesitar dos estructuras como esta: ¿Notó una diferencia entre la especificación RFC y las estructuras declaradas arriba cabecera IP y la versión han intercambiado sus posiciones. Los indicadores urg, ack y psh de la cabecera TCP están en orden inverso . Error. Bueno, esto depende del orden de bytes que se implementa en la arquitectura de la máquina. Hay dos tipos: Little Endian y Big Endian. En Big Endian, los bytes y bits están ordenados en su orden normal cuando los leemos, lo que significa que el MSB (byte más significativo) viene primero y el LSB (byte menos significativo) duran. Pero en Little Endian, la cosa está totalmente invertida. Y hay que tener en cuenta que todos los bits son bytes invertidos, lo que significa que se invierten en grupos de 8. Esa es la regla para hacer segmentos de tamaños 3 o 5, etc Si es un largo o int, entonces un htons () el trabajo. Bueno, bastante dijo, ahora vamos a hacer nuestro paquete. Obtenga los detalles del host remoto en un destino sockaddrin y llame: donde payload es el tamaño de los datos después del encabezado TCP. Eso es lo que hemos hecho. Para comprobar si los paquetes salían como se esperaba, utilice un sniffer como Ethereal y olfatearlos. Nota: Si tiene un firewall en ejecución, es posible que se bloqueen los paquetes sin procesar. VC se puede utilizar para compilar este código. Simplemente cree un proyecto y ponga este archivo en él y haga clic en Ejecutar. Observe el bucle while. En un bucle, esto enviará demasiados paquetes TCP crudos al sistema de destino. Modifique los valores según la necesidad. Ultima actualizacion en. 27 de noviembre de 2012

No comments:

Post a Comment