sockaddr_in - ¿Cómo envío una matriz de enteros sobre TCP en C?
socket tcp udp c++ (7)
Me hacen creer que write()
solo puede enviar buffers de datos de byte (es decir, caracteres con signo), entonces, ¿cómo envío una matriz de enteros largos utilizando la función C write()
en la biblioteca sys / socket.h?
Obviamente, no puedo convertir o convertir mucho tiempo en char, ya que cualquier número superior a 127 estaría mal formado.
Eché un vistazo a la pregunta, ¿cómo descomponer la matriz de enteros en una matriz de bytes (codificaciones de píxeles) , pero no pude entenderlo? Por favor, ¿podría alguien atontarlo un poco si esto es lo que estoy buscando?
Siguiente pregunta:
¿Por qué obtengo resultados extraños cuando leo una matriz de enteros desde un socket TCP?
Creo que lo que tienes que inventar aquí es un protocolo .
Supongamos que su matriz entera es:
100, 99, 98, 97
En lugar de escribir las entradas directamente en el búfer, "serializaría" la matriz convirtiéndola en una representación de cadena. La cadena podría ser:
"100,99,98,97"
Eso es lo que se enviaría por cable. En el extremo receptor, dividirías la cadena por comas y harías una copia de seguridad de la matriz.
Esto es más estandarizado, es legible por humanos, y significa que la gente no tiene que pensar en órdenes de byte hi / lo y otras cosas tontas.
// Sarcasmo
Si estuvieras trabajando en .NET o Java, probablemente codificarías en XML, así:
<ArrayOfInt><Int>100</Int><Int>99</Int><Int>98</Int><Int>97</Int></ArrayOfInt>
:)
La escritura puede hacer lo que quiera, pero hay algunas cosas que debe tener en cuenta:
1: Puede obtener una escritura parcial que no está en un límite int, por lo que debe estar preparado para manejar esa situación
2: si el código necesita ser portable, conviértalo a una endialeza específica o codifica la endianess en el mensaje.
La forma más sencilla de enviar un int único (suponiendo 4 bytes de entrada) es:
int tmp = htonl(myInt);
write(socket, &tmp, 4);
donde htonl es una función que convierte el int en orden de bytes de red . (De manera similar, cuando lee desde el socket, la función ntohl
puede usarse para convertir de nuevo a orden de bytes de host).
Para una matriz de entradas, primero debería enviar el recuento de miembros de la matriz como int (en orden de bytes de red) y luego enviar los valores int.
Sí, puedes simplemente lanzar un puntero a tu buffer a un puntero a char
, y llamar a write()
con eso. Al convertir un puntero a un tipo diferente en C, no se afecta el contenido de la memoria a la que se apunta; todo lo que hace es indicar la intención del programador de que el contenido de la memoria en esa dirección se interprete de manera diferente.
Solo asegúrate de proporcionar a write()
el tamaño correcto en bytes de tu matriz; ese sería el número de elementos multiplicado por sizeof (long)
tamaño sizeof (long)
de tu caso.
Sería mejor tener la funcionalidad serializar / deserializar en su programa cliente / servidor.
Siempre que desee enviar datos, serialice los datos en un búfer de bytes y envíelos a través de TCP con el recuento de bytes.
Al recibir datos, deserialice los datos del búfer según su propia interpretación.
Puede interpretar el búfer de bytes en cualquier forma que desee. Puede contener tipos de datos básicos, objetos, etc.
Solo asegúrate de cuidar la endia y también alinear cosas.
Declara una matriz de caracteres. En cada ubicación de la matriz, almacene números enteros, no caracteres. Entonces solo mandas eso.
Por ejemplo:
char tcp[100];
tcp[0] = 0;
tcp[1] = 0xA;
tcp[2] = 0xB;
tcp[3] = 0xC;
.
.
// Send the character array
write(sock, tcp, sizeof(tcp));
el prototipo para escribir es:
ssize_t write(int fd, const void *buf, size_t count);
así que mientras escribe en unidades de bytes, puede tomar un puntero de cualquier tipo. Pasar un int*
no será un problema en absoluto.
EDITAR:
Sin embargo, recomiendo que también envíe la cantidad de enteros que planea enviar primero para que el receptor sepa cuánto leer. Algo así (se omite la comprobación de errores por brevedad):
int x[10] = { ... };
int count = 10;
write(sock, &count, sizeof(count));
write(sock, x, sizeof(x));
NOTA: si la matriz proviene de la memoria dinámica (como la malloc
), no puede usar sizeof
en ella. En este caso, el conteo sería igual a: sizeof(int) * element_count
EDITAR:
Como señaló Brian Mitchell , es probable que también deba tener cuidado con los problemas de Endian . Este es el caso al enviar cualquier valor multibyte (como en el recuento que recomendé, así como también cada elemento de la matriz). Esto se hace con las htons
: htons
/ htonl
y ntohs
/ ntohl
.