What is the difference between network byte sequence and machine sequence?

Source: Internet
Author: User
Tags htons
What is the difference between network byte sequence and machine sequence?

 

There are two types of byte sequence: nbo and HBO.

Network byte order ):
It stores data in a sequence from high to low and uses a unified network byte sequence on the network to avoid compatibility issues.

Host byte order (HBO, host byte order ):
HBO varies with different machines and is related to CPU design.

There are two types of computer data storage priorities: high byte priority and low byte priority. Data on the internet is transmitted over the network in high byte precedence. Therefore, for machines that store data in low byte precedence mode, data transmission over the Internet requires conversion.
The first structure type we will discuss is struct sockaddr, which is used to save socket information:
Struct sockaddr {
Unsigned short sa_family;/* address family, af_xxx */
Char sa_data [14];/* 14-byte Protocol address */};
Sa_family is generally af_inet; sa_data contains the IP address and port number of the socket.
There is also a structure type:
Struct sockaddr_in {
Short int sin_family;/* address family */
Unsigned short int sin_port;/* Port Number */
Struct in_addr sin_addr;/* IP Address */
Unsigned char sin_zero [8];/* fill in 0 to keep the same size as struct sockaddr */
};
This structure is more convenient to use. Sin_zero (which is used to fill the sockaddr_in structure with the same length as struct sockaddr) should be set to zero using the bzero () or memset () function. The pointer to sockaddr_in and the pointer to sockaddr can be converted to each other, which means that if the parameter type required by a function is sockaddr, you can convert a pointer to sockaddr_in to a pointer to sockaddr when calling a function; or vice versa. Sin_family is usually assigned af_inet; sin_port and sin_addr should be converted into network byte precedence, while sin_addr does not need to be converted.
We will discuss several bytes sequence conversion functions below:
Htons () -- "host to network short"; htonl () -- "host to network long"
Ntohs () -- "network to host short"; ntohl () -- "network to host long"
Here, h indicates "host", N indicates "network", s indicates "short", and l indicates "long ".
Open socket descriptor, establish binding, and establish connection
The socket function is prototype:
Int socket (INT domain, int type, int Protocol );
The domain parameter specifies the socket type: sock_stream or sock_dgram; Protocol is usually assigned "0 ". The socket () call returns an integer socket descriptor, which you can use later.
Once a socket descriptor is returned through a socket call, you should associate the socket with a port on your local machine (this function is often called when you design a server program. Then you can listen for service requests on this port, and the client generally does not need to call this function ). The BIND function is prototype:
Int BIND (INT sockfd, struct sockaddr * my_addr, int addrlen );
Sockfd is a socket descriptor. my_addr is a sockaddr pointer that points to information such as the local IP address and port number. addrlen is often set to sizeof (struct sockaddr ).
Finally, for the BIND function, you can use the following value assignment to automatically obtain the local IP address and randomly obtain an unused port number:
My_addr.sin_port = 0;/* The system randomly selects an unused Port Number */
My_addr.sin_addr.s_addr = inaddr_any;/* enter the local IP Address */
By setting my_addr.sin_port to 0, the function automatically selects an unused port for you to use. Similarly, by setting my_addr.sin_addr.s_addr to inaddr_any, the system automatically fills in the local IP address. When the BIND () function is successfully called, 0 is returned. When an error is encountered, "-1" is returned and errno is set to the corresponding error number. In addition, when calling a function, do not set the port number to a value smaller than 1024, because 1 ~ 1024 is the reserved port number. You can use any unused port number greater than 1024.
The CONNECT () function is used to establish a TCP connection with the remote server. Its prototype is:
Int connect (INT sockfd, struct sockaddr * serv_addr, int addrlen );
Sockfd is the sockt descriptor of the target server; serv_addr is a pointer containing the IP address and port number of the target server. -1 is returned when an error occurs, and errno contains the corresponding error code. For client program design, you do not need to call BIND (), because in this case, you only need to know the IP address of the target machine, and you do not need to care about which port the customer uses to establish a connection with the server, the kernel automatically selects an unused port for the client to use.
Listen () -- listen for service requests
In a server program, when a socket is bound with a port, you need to listen to the port to process the incoming service requests.
Int listen (INT sockfd, int backlog );
Sockfd is the socket descriptor returned by the Socket System Call. Backlog specifies the maximum number of requests allowed in the Request queue. incoming connection requests will wait for accept () in the queue (refer to below ). Backlog limits the number of requests waiting for service in the queue. The default value is 20 for most systems. When the listen encounters an error,-1 is returned, and errno is set to the corresponding error code.
Therefore, server programs generally call functions in the following order:
Socket (); BIND (); Listen ();/* accept () goes here */
Accept () -- connection port service request.
When a client tries to connect to the port listened by the server, the connection request will wait in queue for the server accept. Call the accept () function to establish a connection for it. The accept () function returns a new socket descriptor for this new connection. The server can continue to listen on the previous socket and send and Recv () (receive) data on the new socket descriptor:
Int accept (INT sockfd, void * ADDR, int * addrlen );
Sockfd is the socket descriptor to be monitored. ADDR is usually a pointer to the sockaddr_in variable, this variable is used to store the information of the host requesting the service (a host sends this request from a port); addrten is usually a point value of sizeof (struct sockaddr_in). When an error occurs, a-1 value is returned and the corresponding errno value is set.
Send () and Recv () -- Data Transmission
These two functions are used for data transmission on the connected socket.
The send () function is prototype:
Int send (INT sockfd, const void * MSG, int Len, int flags );
Sockfd is the socket descriptor you want to use to transmit data, and MSG is a pointer to the data to be sent.
Len is the length of data in bytes. Flags is usually set to 0 (for the usage of this parameter, refer to the man Manual ).
Char * MSG = "beej was here! "; Int Len, bytes_sent ;......
Len = strlen (MSG); bytes_sent = Send (sockfd, MSG, Len, 0 );......
The send () function returns the number of actually sent bytes, which may be less than the data you want to send. Therefore, the return value of send () needs to be measured. When the return value of send () does not match Len, this situation should be processed.
The Recv () function is prototype:
Int Recv (INT sockfd, void * Buf, int Len, unsigned int flags );
Sockfd is the socket descriptor for receiving data, Buf is the buffer for storing received data, and Len is the buffer length. Flags is also set to 0. Recv () returns the number of actually received bytes, or if an error occurs,-1 is returned and the corresponding errno value is set.
Sendto () and recvfrom () -- Data Transmission Using Datagram
In the connectionless datagram socket mode, because the local socket does not establish a connection with the remote machine, the destination address should be specified when sending data. The prototype of the sendto () function is:
Int sendto (INT sockfd, const void * MSG, int Len, unsigned int flags, const struct sockaddr * To, int tolen );
This function has two more parameters than the send () function. To indicates the IP address and port number of the host, while tolen is often assigned sizeof (struct sockaddr ). The sendto function also returns the actual length of data bytes or-1 in case of a sending error.
The original recvfrom () function is:
Int recvfrom (INT sockfd, void * Buf, int Len, unsigned int flags, struct sockaddr * From, int * fromlen );
From is a variable of the struct sockaddr type, which saves the IP address and port number of the source machine. Fromlen is often set to sizeof (struct sockaddr ). When recvfrom () is returned, fromlen contains the number of data bytes actually stored in from. The recvfrom () function returns the number of bytes received or-1 if an error occurs, and the corresponding errno is set.
It should be noted that when you call the connect () function for the datagram socket, you can also use send () and Recv () for data transmission, however, this socket is still a datagram socket and uses the UDP Service at the transport layer. However, when sending or receiving data reports, the kernel automatically adds the object and source address information.
Close () and Shutdown () -- end Data Transmission
After all data operations are completed, you can call the close () function to release the socket and stop any data operations on the socket: Close (sockfd );
You can also call the shutdown () function to close the socket. This function allows you to stop data transmission in a certain direction, while data transmission in one direction continues. For example, you can close the write operation of a socket and allow the socket to continue to accept data until all data is read.
Int Shutdown (INT sockfd, int how );
The meaning of sockfd is obvious, and the parameter How can be set to the following values:
· 0 ------- you are not allowed to continue receiving data.
· 1 ------- data cannot be sent again
· 2 ------- no data can be sent or received. If both are allowed, close () is called ()
If the shutdown operation succeeds, 0 is returned. If an error occurs,-1 is returned (and the corresponding errno is set ).
DNS-Domain Name Service Functions
Because IP addresses are hard to remember and read/write, in order to facilitate read/write memory, people often use domain names to represent hosts, which requires domain name and IP address conversion. The gethostbyname () function completes this conversion. The function prototype is:
Struct hostent * gethostbyname (const char * Name );
The function returns a schema type named hosten, which is defined as follows:
Struct hostent {
Char * h_name;/* Host's official domain name */
Char ** h_aliases;/* an array of host aliases ending with null */
Int h_addrtype;/* return address type, in the Internet environment is AF-INET */
Int h_length;/* the length of the address in bytes */
Char ** h_addr_list;/* an array ending with 0, containing all addresses of the Host */
};
# Define h_addr h_addr_list [0]/* The first address in H-ADDR-list */

2. Convert the host's unsigned long value to the network byte sequence (32 bits): Why? Because different computers use different bytes to store data. Therefore, any reference from the Winsock function to the IP address and port number and the IP address and port number sent to the Winsock function are organized in the network order.
U_long htonl (u_long hostlong );
Example: htonl (0) = 0
Htonl (80) = 1342177280

3. Converting the unsigned long number from the byte sequence of the network to the host byte sequence is the inverse function of the above function. U_long ntohl (u_long netlong );
Example: ntohl (0) = 0
Ntohl( 1342177280) = 80

4. Convert the host's unsigned short value to the network byte order (16 bits) for the same reason: 2: u_short htons (u_short hostshort );
Example: htonl (0) = 0
Htonl (80) = 20480

5. Converting the unsigned short number from the network byte order to the host byte order is the inverse function of the above function. U_short ntohs (u_short netshort );
Example: ntohs (0) = 0
N tohsl (20480) = 80

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.