Soy nuevo en la programación de la cavidad y estoy tratando de entender el funcionamiento de htons(). He leído un par de tutoriales en Internet, como este y este uno, por ejemplo. Pero yo no podía entender lo que htons() hace exactamente. He probado el código siguiente:

#include <stdio.h>
#include <sys/types.h> 
#include <sys/socket.h>
#include <netinet/in.h>
int main( int argc, char *argv[] )
{
int sockfd, newsockfd, portno, clilen;
char buffer[256];
struct sockaddr_in serv_addr, cli_addr;
int  n;
/* First call to socket() function */
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) 
{
perror("ERROR opening socket");
exit(1);
}
/* Initialize socket structure */
bzero((char *) &serv_addr, sizeof(serv_addr));
portno = 5001;
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);
/* Now bind the host address using bind() call.*/
if (bind(sockfd, (struct sockaddr *) &serv_addr,
sizeof(serv_addr)) < 0)
{
perror("ERROR on binding");
exit(1);
}
/* Now start listening for the clients, here process will
* go in sleep mode and will wait for the incoming connection
*/
listen(sockfd,5);
clilen = sizeof(cli_addr);
/* Accept actual connection from the client */
newsockfd = accept(sockfd, (struct sockaddr *)&cli_addr, 
&clilen);
if (newsockfd < 0) 
{
perror("ERROR on accept");
exit(1);
}
/* If connection is established then start communicating */
bzero(buffer,256);
n = read( newsockfd,buffer,255 );
if (n < 0)
{
perror("ERROR reading from socket");
exit(1);
}
printf("Here is the message: %s\n",buffer);
/* Write a response to the client */
n = write(newsockfd,"I got your message",18);
if (n < 0)
{
perror("ERROR writing to socket");
exit(1);
}
return 0; 
}

El valor de sin_port se muestra como 35091 durante la depuración y yo no entiendo cómo portno cambiado de 5001 a 35091. Podría alguien explicar la razón por la que el cambio en el valor por favor?

  • ¿Cuál es su comprensión de lo que htons() hace? Tienen que leer esto: en.wikipedia.org/wiki/Endianness.
  • De acuerdo Linux manual de La htons() función convierte el unsigned short integer hostshort de acogida de la orden de byte de orden de byte de red.
  • Sé grandes Endianne y poco Endianne, pero no sé el funcionamiento de htons() exactamente!!!
  • ¿qué sucede si cambia el tipo de portno a uint16_t?
  • El INADDR_* constantes son locales de orden de bytes y también debe ser intercambiado a la red de la orden con htonl (no htons), como en htonl(INADDR_ANY). Usted está consiguiendo solamente sin esto porque INADDR_ANY pasa a ser cero, lo que byte se intercambia a cero. Si usted utiliza INADDR_LOOPBACK, no funcionaría.
InformationsquelleAutor User123422 | 2013-10-06

4 Comentarios

  1. 92

    Tiene que ver con el orden en que los bytes se almacenan en la memoria. El número decimal 5001 es 0x1389 en hexadecimal, por lo que los bytes de los involucrados son 0x13 y 0x89. Muchos dispositivos almacenan números en little-endian formato, lo que significa que el byte menos significativo primero. Así, en este ejemplo particular, esto significa que en la memoria el número de 5001 será almacenado como

    0x89 0x13

    La htons() función se asegura de que los números se almacenan en la memoria en el orden de byte de red, que es con el byte más significativo primero. Por lo tanto, el intercambio de los bytes que componen el número para que en la memoria de los bytes se almacenan en el orden

    0x13 0x89

    En un little-endian de la máquina, el número de bytes intercambiados es 0x8913 en hexadecimal, que es 35091 en notación decimal. Tenga en cuenta que si estuviera trabajando en un big-endian de la máquina, el htons() función no necesita hacer ningún intercambio, ya que el número ya estaría almacenado en el camino correcto en la memoria.

    La razón fundamental de todo este intercambio tiene que ver con los protocolos de red en uso, que requieren la transmisión de paquetes para el uso de orden de byte de red.

  2. 28

    htons es host-to-network short

    Esto significa que funciona en 16 bits enteros cortos. es decir, de 2 bytes.

    Esta función cambia el peso de un corto.

    Su número de parte:

    0001 0011 1000 1001 = 5001

    Cuando el peso se cambia, cambia las dos bytes:

    1000 1001 0001 0011 = 35091

    • ¿quiere usted decir que 0001 0011 son host bytes y 1000 1001 red son las despedidas?
    • nope, lo tienes mal. Aunque la forma binaria de 5001 es «‘0001 0011’ ‘1000 1001′», cuando el almacenamiento en un LittleEndian máquina que almacena los bytes en el orden opuesto («‘1000 1001’ ‘0001 0011′»). Piensa acerca de esto; si ‘a’ y ‘B’ representa ocho bits cada uno, el número binario ‘AB’ será almacenado como » BA » en un LittleEndian de la máquina (google ‘Peso’ si usted necesita saber por qué). ‘htons () es una función conveniente que se utiliza para convertir cualquier corto en formato big-endian (‘AB’ formato), ya que es la «Orden de Byte de Red’.
    • youtube.com/watch?v=NcaiHcBvDR4 En la última parte de este video el chico explica el htons función.
  3. 5

    la htons() función convierte los valores entre el host y el byte de red pedidos. Hay una diferencia entre big-endian y little-endian y orden de byte de red dependiendo de su equipo y de la red de protocolo en uso.

  4. 2

    Se realiza para mantener el arreglo de bytes que se envían en la red(Endianness). Dependiendo de la arquitectura de su dispositivo,los datos se pueden organizar en la memoria, ya sea en el formato big endian o little endian format. En la creación de redes, llamamos a la representación de orden de bytes de la red, por orden de byte y de nuestro anfitrión, que se llama host byte order. Toda orden de byte de red es en formato big endian.Si el anfitrión de la memoria de arquitectura de computadores es en formato little endian,htons() la función de convertirse en necesidad, pero en el caso de big endian formato de la arquitectura de la memoria,no es necesario.Usted puede encontrar el endianness de su equipo mediante programación también de la siguiente manera:->

       int x = 1;
    if (*(char *)&x){
    cout<<"Little Endian"<<endl;
    }else{
    cout<<"Big Endian"<<endl;
    }

    y, a continuación, decidir si usar htons() o no.Pero con el fin de evitar la línea anterior,podemos escribir siempre htons() aunque no hay cambios para el Big Endian basado en la arquitectura de la memoria.

Dejar respuesta

Please enter your comment!
Please enter your name here