Socket Communication Process

Source: Internet
Author: User

It is the general process of a TCP-based client/server program:


After the server calls socket (), BIND (), and listen () to complete initialization, it calls accept () to block and wait, and is in the listening port State. After the client calls socket () to initialize, call connect () to issue SYN segments and block wait for the server to respond, the server responds to a SYN-ACK segment, the client returns from connect () Upon receipt, and responds to an ACK segment at the same time, the server returns the result from accept () After receiving the message.

Data transmission process:

After a connection is established, the TCP protocol provides full-duplex communication services. However, generally, the client/server program initiates a request actively, and the server passively processes the request in a one-Answer manner. Therefore, the server immediately calls read () after returning data from accept (). The read socket is like a read pipeline. If no data arrives, the client blocks the wait. In this case, the client calls write () the server sends a request to the server. After receiving the request, the server returns it from read () and processes the request from the client. During this period, the client calls read () to block waiting for the server's response, and the server calls write () send the processing result back to the client and call read () again to block the next request. After receiving the result, the client returns the result from read () and sends the next request.

If the client has no more requests, call close () to close the connection. Just like the pipeline closed by the write end, the server returns 0 for read, in this way, the server knows that the client has closed the connection and also calls close () to close the connection. Note: After either party calls close (), both transmission directions of the connection are closed and data cannot be sent. If one party calls Shutdown (), the connection is in the semi-closed state and can still receive data from the other party.

When learning the socket API, pay attention to how the application interacts with the TCP protocol layer: * what actions the TCP protocol layer performs when the application calls a socket function, such as calling connect () SYN segment * How does the application know the status changes at the TCP protocol layer? For example, if a blocked socket function returns, the TCP protocol receives some segments, such as read () if 0 is returned, the fin segment is received.

SeeSocketCommunication Process

Figure 12.9 socket communication process

1. Create a socket

Insys/socket.h.

int socket(int family, int type, int protocol);

Socket () opens a network communication port. If it succeeds, a file descriptor is returned like open, an application can use read/write to send and receive data over the network like a read/write file. If a socket () call fails,-1 is returned. For IPv4, the family parameter is set to af_inet. For TCP, the type parameter is set to sock_stream, which indicates the stream-oriented transmission protocol. If the UDP protocol is used, the type parameter is specified as sock_dgram, which indicates the datagram-oriented transmission protocol. The Protocol parameter is described in the following code: 0.

When Linux uses the socket () system to call a new socket, it needs to pass the socket address family identifier, socket type and Protocol. Its function is defined in net/socket. C:

Asmlinkagelong sys_socket (INT family, int type, int Protocol)

{

Int retval;

Struct socket * sock;

 

Retval = sock_create (family, type, protocol, & sock );

If (retval <0)

Goto out;

 

Retval = sock_map_fd (sock );

If (retval <0)

Goto out_release;

 

Out:

/* It may be already another descriptor 8) Not kernel problem .*/

Return retval;

 

Out_release:

Sock_release (sock );

Return retval;

}

In fact, a socket is a special opened file for a user program. A special file type is defined for sockets in the kernel to form a special file system sockfs, which is defined in net/socket. C:

Static struct vfsmount * sock_mnt;

Static declare_fstype (sock_fs_type, "sockfs", sockfs_read_super, fs_nomount );

 

During system initialization, you must use kern_mount () to install the file system. There is a vfsmount Data Structure Used as the connector during installation. The address of this structure is saved in a global sock_mnt pointer. Creating a socket is to create a special file or a node in the sockfs file system and build a complete data structure required to implement the socket function. Therefore, the sock_create () function first creates a socket data structure and maps it to an opened file to allocate and initialize the Socket Structure and sock structure.

The newly created BSD socket data structure contains a pointer to the socket routine of the address family. This pointer is actually the address of the proto_ops data structure.

The socket type of BSD socket is set to the requested sock_stream or sock_dgram. Then, the kernel uses the information in the proto_ops data structure to call the unique creation routine of the address family.

Then, the kernel allocates an idle file descriptor from the FD vector of the current process. The file data structure pointed to by this descriptor is initialized. The initialization process includes directing the file operation set pointer to the BSD file operation set supported by the BSD socket interface. All subsequent socket (File) operations will be directed to this socket interface, and the socket interface will further call the operation routine of the address family to pass the operation to the underlying address family, 12.10.

In fact, the Socket Structure and sock structure are two aspects of the same thing. If the socket structure is for the process and system call interface, then the sock structure is for the underlying driver. However, why not merge the two data structures into one?

Socket is a special file system. Therefore, a component of the Union in the inode structure is used as the socket structure. Its definition is as follows:

Struct inode {

...

Union {

...

Struct socket socket_ I;

}

}

Due to the special nature of socket operations, this structure requires a large number of structural components. However, if we put all these structural components in the socket structure, the union in the inode structure will become very large, and thus the inode structure will become very large. For other file systems, this Union component does not need to be so large. Therefore, the structure components required by the socket are split into two parts, and the part closely related to the file system is placed in the socket structure, A data structure is composed of a portion closely related to the communication, that is, the sock structure. Because these two pieces of data are logically integrated, we need to point each other through pointers to form a one-to-one relationship.

2.Bind the address on the inet BSD socket

To listen to incoming Internet connection requests, each server needs to establish an Inet BSD socket and bind its own address to the socket. The binding operation is mainly performed in the inet socket layer, and some support from the underlying TCP layer and IP layer is also required. After the address is bound to a socket, the socket cannot be used for any other communication. Therefore, the data structure of the socket must be in the tcp_close state. The sockaddr Data Structure passed to the binding operation contains the IP address to be bound and an optional port address. Generally, the address to be bound must be assigned to a network device.
IP address, and the network device should support the inet address family, and the device is available. You can use the ifconfig command to view the active network interfaces. The bound IP address is stored in the rcv_saddr and saddr domains of the sock data structure. These two domains are used for Hash Lookup and sending IP addresses respectively. The port address is optional. If it is not specified, an idle port is selected for the underlying support network.

int bind(int sockfd, const struct sockaddr *myaddr, socklen_t addrlen);

The network address and port number listened on by the server program are usually fixed. After the client program learns the address and port number of the server program, it can initiate a connection to the server, therefore, the server needs to call bind to bind a fixed network address and port number. If BIND () is successful, 0 is returned. If BIND () fails,-1 is returned.

BIND () is used to bind sockfd and myaddr, so that the file descriptor used for network communication listens to the address and port number described by myaddr. As mentioned above, struct sockaddr * is a common pointer type. The myaddr parameter can actually accept the sockaddr struct of multiple protocols, and their lengths are different, therefore, the third parameter addrlen is required to specify the length of the struct. In our program, the myaddr parameter is initialized as follows:

bzero(&servaddr, sizeof(servaddr));servaddr.sin_family = AF_INET;servaddr.sin_addr.s_addr = htonl(INADDR_ANY);servaddr.sin_port = htons(SERV_PORT);

First, clear the entire struct, set the address type to af_inet, and the network address to inaddr_any. This macro indicates any local IP address, because the server may have multiple NICs, each Nic may also be bound to multiple IP addresses. In this way, you can listen on all IP addresses until a connection is established with a client to determine which IP address to use and the port number is serv_port, we define 8000.

When the underlying network device receives a packet, it must pass the packet to the correct Inet and BSD Sockets for processing. Therefore, TCP maintains multiple hash tables, it is used to find the addresses of incoming IP messages and direct them to the correct socket/sock pairs. TCP does not add the bound sock data structure to the hash table during the binding process. During this process, it only checks whether the requested port number is currently in use. In the listener operation, the sock structure is added to the TCP hash table.

 

3.Establish a connection on the inet BSD socket)

After a socket is created, the socket can be used not only to listen to inbound connection requests, but also to establish outbound connection requests. Either way involves an important process: creating a virtual circuit between two applications. An outbound connection can only be established on an Inet BSD socket in the correct state. Therefore, it cannot be established on a socket that has established a connection or a socket used to listen to an inbound connection. That is to say, the status of the BSD socket data structure must be ss_unconnected.

During the connection establishment process, the two TCP sides need to perform three "handshakes". The specific process is described in section 2-network protocol. If TCP sock is waiting for the incoming message, the sock structure is added to the tcp_listening_hash table. In this way, the incoming TCP message can be directed to the sock data structure.

Because the client does not need a fixed port number, you do not need to call BIND (). The client port number is automatically allocated by the kernel. Note: the client does not allow BIND () calls, but does not need to call BIND () to fix a port number. The server does not have to call BIND (), but if the server does not call BIND (), the kernel automatically assigns a listening port to the server. Each time the server is started, the port number is different and the client will have trouble connecting to the server.

int connect(int sockfd, const struct sockaddr *servaddr, socklen_t addrlen);

The client needs to call connect () to connect to the server. The parameters of connect and bind are the same. The difference is that the parameters of BIND are their own addresses, while the parameters of Connect are the addresses of the other party. If connect () is successful, 0 is returned. If an error occurs,-1 is returned.

 

4. listener (Listen) Inet BSD socket

 

int listen(int sockfd, int backlog);

A typical server program can serve multiple clients at the same time. When a client initiates a connection, the accept () called by the server returns and accepts the connection, if a large number of clients initiate a connection and the server is too late to process it, the client that has not been accept will be in the connection waiting state, and listen () declares that sockfd is in the listening state, A maximum of backlog clients are allowed to be in the reception status. If more connection requests are received, ignore them. If listen () is successful, 0 is returned. If yes,-1 is returned.

After a socket is bound to an address, the socket can be used to listen for incoming connections dedicated to the bound address. Network applications can also listen for sockets before the address is bound. At this time, the inet socket layer will use the idle port number and automatically bind it to the socket. The socket listening function changes the socket status to tcp_listen.

When an incoming TCP connection request is received, TCP establishes a new sock data structure to describe the connection. When the connection is eventually accepted, the new sock data structure will be changed to the bottom_half part of the TCP connection kernel. In this case, it will clone the information that contains the connection request passed into sk_buff, the cloned information is queued in the receive_queue queue listening to the sock data structure. The cloned sk_buff contains a pointer to the new sock data structure.

 

5.Accept the connection request (accept)

 

The accept operation is performed on the listening socket, and a new socket data structure is obtained from the listening socket. The process is as follows: the accept operation is first transmitted to the support protocol layer, that is, Inet, to accept any incoming connection requests. On the contrary, the accept operation is further passed to the actual protocol, such as TCP. The accept operation can be blocked or non-blocking. If the accept operation is non-blocking, if there is no acceptable incoming connection, the accept operation will fail, and the new socket data structure will be discarded. When the accept operation is blocked, the network application that executes the blocking operation will be added to the waiting queue and remain suspended until a TCP connection request is received. When a connection request arrives
Sk_buff is discarded, and the new sock data structure established by TCP is returned to the inet socket layer. Here, the sock data structure establishes a link with the previously established new socket data structure. The file descriptor (FD) of the new socket is returned to the network application. Then, the application can use this file descriptor to perform socket operations on the new inetbsd socket.

int accept(int sockfd, struct sockaddr *cliaddr, socklen_t *addrlen);

After the three-party handshake is complete, the server calls accept () to accept the connection. If the server still does not have a client connection request when it calls accept (), it will block waiting until a client connection comes up. Cliaddr is an outgoing parameter. When accept () returns, it returns the outgoing client address and port number. The addrlen parameter is a value-result argument. It is used to pass in the cliaddr length provided by the caller to avoid Buffer Overflow, the actual length of the client address struct is transmitted (it is possible that the buffer provided by the caller is not fully occupied ). If the cliaddr parameter is null, the client address is not concerned.

Note: After receiving the incoming request, if the server can accept the request, the server must create a new socket to accept the request and establish a communication connection (the socket used for listening cannot be used to establish a communication connection, the server and the customer can use the established communication connection to transmit data.

Address: http://oss.org.cn/kernel-book/ch12/12.3.4.htm

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.