Socket in Linux Network Programming (I): Socket overview and byte order and address conversion functions

Source: Internet
Author: User
Tags unix domain socket

1. What is socket?

A socket can be considered as a programming interface between a user process and the kernel network protocol stack.
Socket can be used not only for inter-process communication on the local machine, but also for inter-process communication between different hosts on the network.


Socket API is an abstract network programming interface, applicable to various underlying network protocols, such as IPv4, IPv6, and Unix domain socket to be discussed later. However, the address formats of various network protocols are different, as shown in:


The IPv4 and IPv6 address formats are defined in netinet/in. H. IPv4 addresses are represented by the sockaddr_in structure, including 16-bit port numbers and 32-bit IP addresses, as shown below:


Struct sockaddr_in {
Sa_family_t sin_family;/* address family: af_inet */
In_port_t sin_port;/* port in network byte order */
Struct in_addr sin_addr;/* Internet address */

Char sin_zero [8];/* pad bytes, set to zero is OK */
};


/* Internet address .*/
Struct in_addr {
Uint32_t s_addr;/* address in network byte order */

};


The IPv6 address is represented by the sockaddr_in6 struct, including the 16-bit port number, 128-bit IP address, and some control fields. The address format of Unix domain socket is defined in sys/UN. h and is represented by the sockaddr_un struct. The prefixes of various socket address struct are the same. The first 16 bits indicate the length of the entire struct (not all UNIX implementations have length fields, such as Linux does not ), the last 16 bits indicate the address type. IPv4, IPv6, and Unix
Domain socket address types are defined as constants af_inet, af_inet6, and af_unix. In this way, as long as you get the first address of a sockaddr struct, you do not need to know which type of sockaddr struct is, you can determine the content of the struct according to the address type field. Therefore, the socket API can accept various types of sockaddr struct pointers as parameters, such as bind, accept, connect, and other functions, the parameters of these functions should be designed to be void * type to accept various types of pointers. However, the implementation of sock APIS is earlier than that of ansi c, and there is no void * type at that time, therefore, the parameters of these functions use struct.
Sockaddr * indicates the generic address structure, as shown below:

Struct sockaddr {
Sa_family_t sin_family;
Char sa_data [14];
};


Sin_family: Specifies the address family.
Sa_data: It is determined by sin_family.


Force type conversion before passing parameters, for example:

Struct sockaddr_in servaddr;

/* Initialize servaddr *

/BIND (listen_fd, (struct sockaddr *) & servaddr, sizeof (servaddr ));


Ii. Network byte order

Byte order
Big endian)
MSB: most significant bit is stored at the lowest memory address, and LSB: Lowest significant bit is stored at the highest memory address.
Little endian)
MSB: most significant bit is stored at the highest memory address, and LSB: Lowest significant bit is stored at the lowest memory address.
Host byte order
Different hosts have different byte sequences. For example, x86 is a small byte sequence, Motorola 6800 is a large byte sequence, and arm is configurable.

Network byte order
The Network byte sequence is defined as the large-end byte sequence.

To make the network program portable, the same C code can run properly after compilation on both the large and small computers, you can call the following database functions to convert the network byte sequence and host byte sequence.


# Include <ARPA/inet. h>

Uint32_t htonl (uint32_t hostlong );

Uint16_t htons (uint16_t hostshort );

Uint32_t ntohl (uint32_t netlong );

Uint16_t ntohs (uint16_t netshort );


These function names are easy to remember. h Represents host, N represents network, l represents 32-bit long integers, and s represents 16-bit short integers. For example, htonl converts a 32-bit long integer from the host's byte order to the network's byte order, for example, converting an IP address before sending it. If the host is in the small-end byte order, these functions convert the parameters and return them. If the host is in the large-end byte order, these functions are not converted and the parameters are returned intact.

Below is a small program to test the Host size:

C ++ code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/*************************************** **********************************
> File name: byteorder. c
> Author: Simba
> Mail: dameng34@163.com
> Created time: Fri 01 Mar 2013 04:16:08 pm CST
**************************************** ********************************/

# Include <stdio. h>
# Include <ARPA/inet. h>

Int main (void)
{
Unsigned int x = 0x12345678;
Unsigned char * P = (unsigned char *) & X;
Printf ("% x \ n", P [0], p [1], p [2], p [3]);

Unsigned int y = htonl (X );
P = (unsigned char *) & Y;
Printf ("% x \ n", P [0], p [1], p [2], p [3]);

Return 0;
}

Output:

Simba @ Ubuntu :~ /Documents/code/linux_programming/UNP/socket $./byteorder
78 56 34 12
12 34 56 78

That is, the local host is in the small-end byte order, and the network byte order after htonl conversion, that is, the large-end.

Iii. address conversion functions

The member struct in_addr sin_addr in the sockaddr_in struct mentioned above represents a 32-bit IP address. However, we usually use a dot-decimal string to represent the IP address. The following functions can be converted between string representation and in_addr representation.


Function for converting string to in_addr:


# Include <ARPA/inet. h>

Int inet_aton (const char * strptr, struct in_addr * addrptr );

In_addr_t inet_addr (const char * strptr );

Int inet_ton (INT family, const char * strptr, void * addrptr );

Note that the converted 32-bit value is in the network byte order.

Function for converting in_addr to string:

Char * inet_ntoa (struct in_addr inaddr );

Const char * inet_ntop (INT family, const void * addrptr, char * strptr, size_t Len );

Note that the 32-bit value is also in the network byte order.

Inet_ton and inet_ntop can not only convert the in_addr of IPv4, but also the in6_addr of IPv6. Therefore, the function interface is void * addrptr.


The following is a demo of a small program:

C ++ code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/*************************************** **********************************
> File name: addr_in.c
> Author: Simba
> Mail: dameng34@163.com
> Created time: Fri 01 Mar 2013 04:16:08 pm CST
**************************************** ********************************/

# Include <stdio. h>
# Include <ARPA/inet. h>

Int main (void)
{

Unsigned int ADDR = inet_addr ("192.168.0.100"); // The converted bytes are in the network byte sequence (large end)
Printf ("add = % u \ n", ntohl (ADDR ));

Struct in_addr ipaddr;
Ipaddr. s_addr = ADDR;
Printf ("% s \ n", inet_ntoa (ipaddr ));

Return 0;
}

Output:

Simba @ Ubuntu :~ /Documents/code/linux_programming/UNP/socket $./addr_in
Add = 3232235620
192.168.0.100

Note: When printing the ADDR, it is first converted to the host's byte sequence. Otherwise, the output may be a negative number.


Iv. Socket Type

Stream socket (sock_stream)
It provides connection-oriented and reliable data transmission services. Data is transmitted without errors or duplicates, and received in the sending order.
Datagram socket (sock_dgram)
Provides the connectionless service. No error-free guarantee is provided, data may be lost or duplicated, and the receiving order is disordered.
Original socket (sock_raw)


Refer:

Linux C Programming one-stop learning

Chapter 1 TCP/IP details

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.