Non-blocking connect () and accept ()
A. Select () function
The criteria for the Select () function to read:
1> The set interface has data readable
2>. The read half of the connection closes (that is, the TCP connection that received the Fin). A read operation on such a set of interfaces will not block and return 0 (that is, to return EOF).
3> The socket interface is a listener socket and the number of completed connections is not 0.
4> There is a set of interface errors to be processed, the read operation on such a set of interfaces will not block and return-1, and set errno, which can be obtained by invoking the GetSockOpt function by setting the SO_ERROR option.
The criteria that the Select () function prepares to write:
1> a socket has a space that can be used for writing.
2>. The writing of this connection is closed, and writing to such a socket will produce a sigpipe signal.
3>. The socket connects to connect in a non-blocking manner, and the connection has been set up asynchronously, or connect has failed.
4> There is a set of interface errors to be processed.
Two. Accept () function
1. Blocking mode
Blocking mode is lowered with the accept () function, and the process goes to sleep when no new connection is made.
2. Non-blocking mode
Non-blocking mode is lowered with the accept () function and a ewouldblock error is returned when no new connection is made.
Non-blocking mode select () + Accept ()
SOCKFD = Listen_tcp (); Socket (), bind (), listen ()
Fd_set (SOCKFD, RSet);
while (1) {
ret = SELECT (SOCKFD + 1, rset, NULL, NULL, timeout); Wait for an event to occur: A new connection, or data, or fin, or rst arrives
if (select () returns timeout) {//select () timeout
printf ("Log Printing");
Sleep (1);
Continue
}
else if (Fd_isset (Sockfd,&rset)) {//To determine whether the handle is readable, the return true represents readable, and the read represents a new connection.
CONNFD = Accept (SOCKFD, ...);
}
else if (select () returns an error) {
return-1;
}
Pthread_create (Thread_recv_data, CONNFD, ...); Creates a thread to handle a new connection.
Close ();
}
Three. Connect () function
1. Blocking mode
The client call to the Connect () function fires the TCP's three-way handshake, but returns only if the connection is successful or error-making. There are several possible scenarios for the returned error:
1> If the TCP client does not receive a response from the SYN section, the Etimedout is returned and the blocking mode timeout is between 75 seconds (4.4BSD kernel) and minutes.
2> If RST is responding to a customer's SYN, it means that the server host does not have a process waiting to connect to it on the port we specify (for example, the server process may not be started), which is called a hard error, and the guest
As soon as the user receives the RST, it returns the error econnrefused.
3>. If a client sends a SYN that throws a destination unreachable ICMP error on the middle router, the error number is returned after multiple attempts to send a failure of Ehostunreach or Enetunreach.
Add: Three cases of RST, one is SYN arrives at a port but there is no server listening on this port, and TCP wants to cancel an existing connection, and the third is TCP to receive a non-existent connection.
Section.
2. Non-blocking mode of operation
The call to the Connect () function returns the einprocess error immediately, but the three-way handshake for TCP communication is in progress, so you can use the Select function to check whether the connection was established successfully.
The implementation from Berkeley has two rules related to select and non-blocking:
1> When a connection is successfully established, the descriptor becomes writable.
2> When the connection is established, the descriptor becomes readable and writable. The errno = 0 of the getsockopt () function is writable only.
Non-blocking mode select () + Connect ()
while (1) {
ret = connect ();
if (errno = = einprocess) {//Now TCP's three-way handshake continues
Select (...)/wait for an event to occur: or a new connection, or timeout
if (Fd_isset (Sockfd,&wset)) {//judgment handle writable, cannot represent successful connection.
GetSockOpt (...);
if (errno = = 0) {//Establish connection success
}
}
else if (select () returns timeout) {
Sleep (1);
Continue ();
}
}
else if (ret = = 1) {
Connect failed
}
Pthread_create (Thread_send_log, ...); Establish a thread to process a new connection
Close ();
}