interprocess communication (10)-Network sockets socket

Source: Internet
Author: User
Tags message queue

1. Preface

All examples of this post are based on the RHEL6.5 platform (Linux kernal:2.6.32-431.el6.i686).

2. Inter-process communication in the networkThere are many kinds of local interprocess communication (IPC) methods, summed up, presumably can be divided into the following 4 categories:
a). Message delivery. Include pipeline (click this link), FIFO (point this link), Message queue (click this link), etc.
b). Shared memory. Include Anonymous and named ( click this link ).
c). Sync. Includes mutexes, condition variables, read and write locks, file and record locks, semaphores, and so on.
d). Remote procedure call. For example, Sun RPC.
However, most of these communication methods are limited to local. How do I communicate between processes in the network? The first issue that needs to be addressed is how to uniquely identify a process. Processes can be uniquely identified locally through the process PID, but it is not possible to rely on this in the network alone. In reality, the TCP/IP protocol family has solved this problem, the network layer "IP address" can uniquely identify the host in the network, and the Transport Layer "protocol + port" can uniquely identify the host application (that is, the process). Thus, using this ternary (IP, Protocol, port) can identify the process of the network, the network process communication can use this flag to interact with other processes.

3.socket IntroductionSockets originate from UNIX, and one of Unix/linux's basic philosophies is that "all files" can be manipulated using the "open open-> Read and write write/read-> close" mode. The socket can be seen as an implementation of this pattern, and the socket-related function is the operation on it (read/write I/O, open, close). These functions are described in later chapters.

The origin of the word socket:
The first use in the area of networking was discovered in the IETF RFC33, published on February 12, 1970, by Stephen Carr, Steve Crocker, and Vint Cerf. According to the records of the American Museum of Computer History, Croker wrote: "The elements of a namespace can be called socket interfaces." A socket interface forms one end of a connection, and a connection can be specified entirely by a pair of socket interfaces. "This is about 12 years earlier than the BSD socket interface definition," added the Computer History Museum. ”
As mentioned earlier, the socket can also be considered a file operation, which conforms to the "open->write/read->close" mode, and the socket should provide the corresponding function interface for these operations. The following is an example of TCP, which describes common Sockt interface functions.

4.socket () function

#include <sys/types.h> #include <sys/socket.h>int sockets (int domain, int type, int protocol);
The socket function corresponds to the open operation of the normal file. The open operation of a normal file returns a file descriptor, and the socket () is used to create a socket descriptor (socket descriptor), which uniquely identifies a socket. The socket descriptor is the same as the file descriptor, and subsequent operations are useful to it, using it as a parameter to perform some read and write operations.
Just as you can give fopen a different parameter value to open a different file. When creating a socket, you can also specify different parameters to create different socket descriptors, the three parameters of the socket function are:

· Domain: The Protocol field, also known as the Protocol Family (family). Common protocol families are af_inet, Af_inet6, af_local (or Af_unix,unix domain sockets), Af_route, and so on. The protocol family determines the socket address type, must use the corresponding address in the communication, such as Af_inet decided to use the IPV4 address (32 bits) and the port number (16 bit) combination, Af_unix decided to use an absolute path name as the address.

· Type: Specifies the socket type. Common socket types are sock_stream, Sock_dgram, Sock_raw, Sock_packet, Sock_seqpacket, SOCK_RDM, and so on.

·  Protocol: As the name implies, the protocol is specified. Commonly used protocols are, IPPROTO_TCP, IPPTOTO_UDP, IPPROTO_SCTP, IPPROTO_TIPC, respectively, they correspond to TCP transport protocol, UDP Transmission protocol, STCP Transmission protocol, TIPC transmission protocol.

Note: The above type and protocol can not be arbitrarily combined, such as sock_stream can not be combined with IPPROTO_UDP. When protocol is 0 o'clock, the default protocol corresponding to type types is automatically selected. when we call the socket to create a socket, the returned socket descriptor exists in the Protocol family (address family,af_xxx) space, but does not have a specific address. If you want to assign an address to it, you must call the bind () function, or the system will automatically randomly allocate a port when you call Connect (), listen ().

5.bind () functionAs mentioned above, the bind () function assigns a specific address in the address family to the socket. For example, the corresponding af_inet, Af_inet6 is to assign a IPv4 or IPv6 address and port number combination to the socket.

#include <sys/types.h> #include <sys/socket.h>int bind (int sockfd, const struct SOCKADDR *addr, socklen_t Addrlen);

Parameter SOCKFD:
The socket descriptor, which is created through the socket () function and uniquely identifies a socket. The bind () function is to bind a name to this descriptor.
Parameter addr:
A const struct SOCKADDR pointer that points to the Protocol address to bind to SOCKFD. This address structure differs depending on the address protocol family at the time the socket was created. Refer to section 4.3 for details.
Parameter Addrlen
Corresponds to the length of the address.

Usually when the server is started to bind a well-known address (such as IP address + port number) to provide services, the client can be used to connect the server, and the client does not specify, there is a system automatically assigned a port number and its own IP address combination. This is why the server usually calls bind () before listen, and the client does not invoke it, but instead generates one randomly from the system at Connect ().

6.struct sockaddr Detailed6.1.sockaddr DefinitionUnder Linux mitigation, the struct sockaddr is defined in/usr/include/linux/socket.h, which amounts to 16 bytes. Defined as follows:

typedef unsigned short sa_family_t;struct sockaddr {        sa_family_t     sa_family;    /* Address family, af_xxx       */  //2 bytes        char            sa_data[14];  /* bytes of protocol address */  //14 bytes}
6.2.sockaddr_in Definitionin the Linux environment, struct struct sockaddr_in is defined in/usr/include/netinet/in.h, corresponding to the IPV4 address. It is defined as follows:
/* Structure describing an Internet socket address.  */struct sockaddr_in{    __sockaddr_common (sin_);      2 bytes    in_port_t sin_port;            /* Port number.  */   //2 byte    struct in_addr sin_addr;       /* Internet address.  */  //4 Bytes/    * Pad to size of ' struct sockaddr '.  */  //8 byte    unsigned char sin_zero[sizeof (struct sockaddr)-                           __sockaddr_common_size-                           sizeof (in_ port_t)-                           sizeof (struct in_addr)];    The above character array sin_zero[8] exists to ensure that the size of struct sockaddr_in and struct struct sockaddr are equal};
where the in_port_t type is specifically positioned as:
The struct in_addr is actually a 32-bit IP address.
/* Internet address.  */typedef uint32_t in_addr_t;struct in_addr{    in_addr_t s_addr;  /* address in network byte order */};
6.3.sockaddr contact with sockaddr_instruct SOCKADDR is a universal socket address, while struct sockaddr_in is the address form of a socket in the Internet environment, both of which are 16 bytes in length. The two are parallel structures, and pointers to sockaddr_in structures can also point to sockaddr. In general, it is necessary to cast the SOCKADDR_IN structure into the SOCKADDR structure and re-pass it into the system call function.
The following is a more general example of using sockaddr:
int sockfd;struct sockaddr_in MY_ADDR;SOCKFD = socket (af_inet, sock_stream, 0); my_addr.sin_family = af_inet;     /* Host byte order */my_addr.sin_port = Htons (MyPort); /* short, network byte order */my_addr.sin_addr.s_addr = inet_addr ("192.168.0.1"); Bzero (& (My_addr.sin_zero), 8);   /* Zero the rest of the struct *///memset (&my_addr.sin_zero, 0, 8);//cast sockaddr_in to Sockaddrbind (SOCKFD, (Struct SOC KADDR *) &my_addr, sizeof (struct sockaddr));
6.4.sockaddr_in for IPv6the SOCKADDR_IN structure that corresponds to the IPV6 address is defined as follows:
/* Ditto, for IPV6.  */struct sockaddr_in6{    __sockaddr_common (sin6_);  2 bytes    in_port_t sin6_port;        /* Transport Layer Port # */  //2 byte    uint32_t sin6_flowinfo;     /* IPV6 Flow information */    struct in6_addr sin6_addr;  /* IPV6 Address */    uint32_t sin6_scope_id;     /* IPv6 Scope-id */};
where struct IN6_ADDR is defined as follows:
struct IN6_ADDR {     unsigned char   s6_addr[16];   /* IPV6 address */};
6.5.unix domain Correspondence sockaddr
#define Unix_path_max 108struct Sockaddr_un {sa_family_t sun_family;       /* Af_unix */char Sun_path[unix_path_max]; /* pathname */};
7. Byte orderHost byte-order is what we normally call the big-endian and small-end patterns: Different CPUs have different byte-order types, which are the order in which integers are stored in memory, which is called the host order. The reference standard Big-endian and Little-endian are defined as follows:
A) The Little-endian is the low-bit bytes emitted at the lower address of the memory, high-bit bytes emitted in the memory of the higher address.
b) The Big-endian is the high-bit byte emitted at the low address of the memory, and the low byte is discharged at the upper address of the memory.

Network byte order: The 4-byte value is transmitted in the following order: First, 0~7bit, followed by 8~15bit, then 16~23bit, and finally 24~31bit. This transmission order is called the big-endian byte order. Because all binary integers in the TCP/IP header are required in this order when they are transmitted over the network, it is also referred to as the network byte order. The order of bytes, as the name implies, is greater than the order in which the data of a byte type is stored in memory, and a byte of data does not have a sequential problem.

So: When binding an address to the socket, first convert the host byte order into the network byte order, and do not assume that the host byte order is the same as the network byte order is Big-endian, otherwise it will cause a lot of inexplicable problems. So keep in mind that you don't make any assumptions about the host byte order, so be sure to convert it into a network byte order and then assign it to the socket.

8.listen () function

#include <sys/types.h> #include <sys/socket.h>int listen (int sockfd, int backlog);
The two parameters are explained in the man manual as follows:
Parameter SOCKFD:
SOCKFD identifies a socket file descriptor that corresponds to the socket type Sock_stream or sock_seqpacket (the SOCKFD argument is a file descriptor that refers to a s Ocket of type Sock_stream or Sock_seqpacket).
Parameter backlog:
The backlog argument defines the maximum length to which the queue of Pending Connections For SOCKFD grow. If a connection request arrives when the queue was full, the client may receive a error with an indication of ECO Nnrefused or, if the underlying protocol supports retransmission, the request may be ignored so, a later reat Tempt at connection succeeds.

A). The backlog is the maximum length to wait for the connection queue. For example, if the backlog is set to 10, when there are 15 client connection requests, the first 10 connection requests are placed in the request queue, and the subsequent 5 requests are rejected.
b). When the link (connect) finishes, one is removed from the connection queue (the Accept function is implemented).
c). When the connection queue is full, the client receives a return value for the connection error, or if the underlying network supports retransmission, the server ignores the request and relies on subsequent retransmission to establish the connection.

As we all know, the TCP connection process can be divided into 3 handshake. In order to maintain these states in the connection process, the server needs to open two queues to hold the two intermediate states. A connection called a "half-connection queue" used to hold a "SYN recvd" state, a TCP connection called a "full connection queue" to hold the "established" state. When a connection to the SYN RECVD queue is received, the connection is removed from the SYN RECVD queue and added to the end of the "established" queue, and the sum of the two queue sizes is determined by the backlog parameter. When calling the Accept function after invoking the Listen function, we actually take a connection from the "Full connection queue" to establish a real TCP connection.
The total size of two queues (backlog) is limited on Linux systems, which can be seen in Cat/proc/sys/net/core/somaxconn, the default value is 128.

In addition, the listen function of the man manual, the backlog has the following paragraph of this description:
The behavior of the backlog argument on TCP sockets changed with Linux 2.2. Now it specifies the queue length for completely established sockets waiting to be accepted, instead of the number of Inco Mplete connection requests. The maximum length of the queue for incomplete sockets can is set Using/proc/sys/net/ipv4/tcp_max_syn_backlog. When Syncookies was enabled there is no logical maximum length and this setting is ignored. See TCP (7) for more information.
The backlog's behavior in TCP has changed before linux2.2. Now it is used to indicate that the 3 handshake has been completed and that the state has changed to the queue length of established, waiting for the accept function to call it. Previously used to indicate the number of connections that have not been completed, that is, in the Syn RECVD state.
For the queue length of a connection that has not yet completed the 3 handshake, you can use the/proc/sys/net/ipv4/tcp_max_syn_backlog to set the settings. The default value is 512.
When Syncookies is set to enable, there is no limit to the maximum length of this logic. This configuration item for the backlog will be ignored.

9.connect () function

#include <sys/types.h> #include <sys/socket.h>int connect (int sockfd, const struct SOCKADDR *addr,socklen_t Addrlen);
TCP and UDP behavior in 9.1.connect ()Connect is a socket connection operation, after the connect operation represents the corresponding socket is connected, the UDP protocol after the socket is created, you can establish communication with multiple server side, and the TCP protocol can only establish communication with one server, TCP does not allow the destination address is a broadcast or multicast address, UDP is allowed. Of course, the UDP protocol can also be the same as the TCP protocol, through connect to specify the other's IP address, port.
After the UDP protocol is connect, the destination address and port are not required to send the datagram via SendTo, and an error is returned if the destination address and port are specified. The UDP protocol allows multiple connect operations to be specified for the same socket, and TCP protocol is not allowed, TCP can only specify one connect operation at a time. The UDP protocol specifies that the second connect operation will be preceded by a first connection and then a second connection is established.
9.2.connect Execution ProcessBefore the client executes the Connect connection server, the following two steps are generally present:
The first step is to establish a connection socket through the socket;
The second step is to bind the address, local port, and of course the binding operation can not be specified.
For UDP protocol: If the binding operation is not specified, the kernel is responsible for the socket binding operation through the following connect operation, and if connect is not specified, then the binding operation has to specify the destination address, port, via socket write operation (SendTo, sendmsg). The socket local address is not specified, and the local port is specified by the kernel, and after the first sendto operation, the local port of Scoket is not changed after the kernel is specified.
For the TCP protocol: If a binding operation is not specified, the kernel is responsible for the socket binding operation through the subsequent connect operation. The kernel determines the out-of-office interface based on the destination address in the socket, and then specifies that the egress interface's IP address is the local address of the socket. The connect operation is essential for the client of the TCP protocol and must be performed.
9.3. Non-blocking ConnectThe establishment of a TCP connection involves a three-time handshake, and the Connect function in the socket needs to wait until the customer receives an ACK for their SYN before returning, which means that each connect function always blocks at least one of its calling processes to the server's RTT time. The RTT fluctuates from a few milliseconds to hundreds of milliseconds or even a few seconds across the WAN from the local area network. During this time, we can perform other processing work in order to achieve parallelism. In this case, you need to use non-blocking connect.

Step 1: Set up non-blocking to initiate the connection
To implement non-blocking connect, first set the SOCKFD to non-blocking. This calls connect to return immediately, handling three cases based on the return value and errno:
(1) If 0 is returned, connect is successful.
(2) If the return value is less than 0, errno is einprogress, indicating that the connection establishment has started but has not yet completed. This is the desired result, not a real error.
(3) If the return value is less than 0,errno is not einprogress, the connection is faulted.
int flags = FCNTL (SOCKFD, F_GETFL, 0); flags |= o_nonblock;fcntl (SOCKFD, F_SETFL, flags); int result = Connect (SOCKFD, saptr , Salen); if (result = =-1) {if (errno! = einprogress) return fail;//else:the socket is non-blocking and the  connection Cannot be completed immediately}if (result = = 0) return succ;
Step 2: Determine readable and writable
The SOCKFD is then added to the read-write listening set of SELECT, and the select determines whether the SOCKFD is writable and handles three situations:
(1) If the connection is established, the other party does not have the data to arrive, then the SOCKFD is writable
(2) If the connection is established before the Select, and the data of the other party has arrived, then the SOCKFD is readable and writable.
(3) If the connection error occurs, the SOCKFD is also readable and writable.
To determine if connect is successful, you have to distinguish between (2) and (3), in both cases sockfd are readable and writable, and the way to differentiate is to call getsockopt to check for errors.
Fd_set WFD; Fd_zero (&WFD); Fd_set (FD, &WFD); if (select (Sockfd+1, NULL, &WFD, NULL, timeoutptr) = =-1) {    close (FD);    return fail;}

Step 3: Use the GetSockOpt function to check for errors
getsockopt (int sockfd, int level, int optname, void *optval, socklen_t *optlen);
In cases where sockfd are both readable and writable, we use getsockopt to check the connection for errors. But there's a portability problem here.
In the event of an error, the implementation of getsockopt originating from Berkeley will return an error in the variable error, getsockopt itself returns 0, while Solaris allows getsockopt to return 1 and save the error in the errno variable. So when judging whether there are errors, you should deal with both cases.

int error=0, result=0;if (Fd_isset (SOCKFD, &WFD)) {socklen_t length = sizeof (error); result = GetSockOpt (SOCKFD, sol_s Ocket, So_error, &error, &length); if (Result < 0 | | ERROR) {close (SOCKFD); if (error) {errno = Err;return fail;} }}





















interprocess communication (10)-Network sockets socket

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.