socket programming twenty-three: the size of the side issues of network data

Different CPU, a 4-byte integer in a memory storage space is different. 4-byte hexadecimal integer of 1 available 2 as follows:

00000000 00000000 00000000 00000001

Some of the CPU in the above order stored in memory, the CPU now reverse some other storage, as follows:

00000001 00000000 00000000 00000000

Failure to consider these issues occur on the send and receive data, because of the different means of preservation order to resolve the order of the received data is different.

Big-endian and little-endian

CPU There are two ways to save data to memory:

  • Big endian (Big Endian): low-order address is stored in the high byte (high byte first).
  • Little-endian (Little Endian): high-order address is stored in the high byte (low byte first).


Description alone is difficult to explain, it might look at an example. Assuming 4-byte int type data stored in address 0x12345678 0x20 starting number, the CPU save big endian manner as shown below:

Integer representation of the big-endian byte 0x12345678
Figure 1: the big-endian byte integer representation 0x12345678


For big endian, the most significant byte is stored in the lower address 0x12, 0x78 least significant byte is stored in the upper address. Little-endian way to preserve as shown below:

The little-endian integer 0x12345678 bytes
Figure 2: the little-endian byte integer representation 0x12345678


Different different CPU to save and parse the data the way (mainstream Intel CPU series is the little-endian), data parsing errors occur when the little-endian and big-endian systems communication systems. Therefore, before transmitting data, to format the data into a unified, - network byte order (Network Byte Order). Unified network byte order is big-endian.

A first host data sequence converted to upper end of the transmission network again, after host B receives the data of the first format and then converted to their resolution.

Network byte order conversion function

In " the bind () and connect () function: a bound socket and establishing a connection " section explains sockaddr_in structure, which it uses network byte order conversion function as follows:


//创建sockaddr_in结构体变量
struct sockaddr_in serv_addr;
memset(&serv_addr, 0, sizeof(serv_addr)); //每个字节都用0填充
serv_addr.sin_family = AF_INET; //使用IPv4地址
serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); //具体的IP地址
serv_addr.sin_port = htons(1234); //端口号

the htons () is used to convert the current host network byte order as the byte order, which hdenotes a host (Host) byte order, non behalf of the network (network) byte order, srepresentative of short, htons is h, to, n, s of the combination, can be understood as "the short type data into byte order from the current host to network byte order."

Common network byte conversion functions are:

  • htons (): host to network short, the short type byte order of data from host to network byte order.
  • ntohs (): network to host short, the short type data from the host to network byte order byte order.
  • htonl (): host to network long, the long type byte order of data from host to network byte order.
  • ntohl (): network to host long, the long type data from the host to network byte order byte order.


Typically, in order to sfunction as a suffix, sis two bytes short, so the port number translation; to la function suffix, lrepresents four bytes long, so the IP address conversion.

Exemplified above function calling procedure:


#include <stdio.h>
#include <stdlib.h>
#include <WinSock2.h>
#pragma comment(lib, "ws2_32.lib")

int main(){
unsigned short host_port = 0x1234, net_port;
unsigned long host_addr = 0x12345678, net_addr;

net_port = htons(host_port);
net_addr = htonl(host_addr);

printf("Host ordered port: %#x\n", host_port);
printf("Network ordered port: %#x\n", net_port);
printf("Host ordered address: %#lx\n", host_addr);
printf("Network ordered address: %#lx\n", net_addr);

system("pause");
return 0;
}

Operating results:
Host ordered Port: 0x1234
Network ordered Port: 0x3412
Host ordered address: 0x12345678
Network ordered address: 0x78563412

Also to be noted that, sockaddr_in save IP addresses of the members for the 32-bit integer, and we are familiar with is dotted decimal notation methods, e.g. 127.0.0.1, which is a string, so in order to assign an IP address, it is necessary to convert the string to an integer of 4 bytes.

the inet_addr () function to complete this conversion. the inet_addr () to convert the string except 32-bit integer, but also network byte order conversion. Consider the following code:


#include <stdio.h>
#include <stdlib.h>
#include <WinSock2.h>
#pragma comment(lib, "ws2_32.lib")

int main(){
char *addr1 = "1.2.3.4";
char *addr2 = "1.2.3.256";

unsigned long conv_addr = inet_addr(addr1);
if(conv_addr == INADDR_NONE){
puts("Error occured!");
}else{
printf("Network ordered integer addr: %#lx\n", conv_addr);
}

conv_addr = inet_addr(addr2);
if(conv_addr == INADDR_NONE){
puts("Error occured!");
}else{
printf("Network ordered integer addr: %#lx\n", conv_addr);
}

system("pause");
return 0;
}

Run Results:
the Network ordered Integer addr: 0x4030201
! Error occured

can be seen from the results of operation, the inet_addr () not only can be converted to 32-bit integer IP addresses, IP addresses can also detect invalid.

Note: the need to explicitly assigned sockaddr_in conversion member host network byte order as the byte order, the TCP protocol is automatically converted to network byte order when transmitting data through the write () / send (), need to call the corresponding function.

Published 33 original articles · won praise 30 · views 20000 +

Guess you like

Origin blog.csdn.net/baidu_15547923/article/details/90230438