For connection oriented socket type (SOCK_STREAM,SOCK_SEQPACKET) reading Write The connection must be established before the data is transmitted , First, the server side socket It must be monitored at an address known to the client , That is to create socket Must be called after bind Bind to a specified address , And then call int listen(int sockfd, int backlog); monitor . At this time, the server socket Allow clients to connect ,backlog The hint was not answered accept The size of the client connection request queue for , The system determines the actual value , The maximum value is defined as SOMAXCONN In the header file <sys/socket.h> Inside . If for some reason the server-side process is not in time accpet If the queue is full due to client connection, the new client connection request will be rejected ( I have encountered this situation in my work ,IONA ORBIX(CORBA middleware ) Because the timeout is not configured, the result is WIFI Abnormal data transmission in the network has been blocked without a chance to call accept Accept new customer requests , Finally, the queue is full and new client connections are rejected ).

call listen Then when a client connection arrives, call int accept(int sockfd, struct sockaddr *restrict addr, socklen_t *restrict len); Accept the client connection, establish the connection, and return the data used for connection transmission socket The descriptor , To monitor socket It can be used to continue listening for client connection requests , Back to socket Descriptors and listening socket The same type . If addr Not for NULL, The client initiates the connection request socket The address information will be sent through addr Go back . If you're listening to socket If the descriptor is in blocking mode, then accept It will block until a client makes a connection request , If you're listening to socket If the descriptor is in non blocking mode, if no client connection request is currently available , Then return to -1(errno Set to EAGAIN). have access to select Function to monitor socket Descriptors are multiplexed , If there is a customer connection request, then select What will be monitored socket The descriptor is set to can read ( Be careful , If you're listening to socket Use for blocking mode select Demultiplexing can result in select return can read But the call accept It's going to be blocked , The reason is calling accept Before the client may take the initiative to close the connection or send RST Abnormally close the connection , therefore select Better with non blocking socket Use it with ).

Client calls int connect(int sockfd, const struct sockaddr *addr, socklen_t len); Initiate a call to the server socket Connection request for , If the client socket If the descriptor is in blocking mode, it will block until the connection is established or the connection fails ( Note that the timeout for blocking mode may be 75 Between seconds and minutes ), And if it's in non blocking mode , Call connect After that, if the connection cannot be established immediately, it returns -1(errno Set to EINPROGRESS, Note that the connection may be established immediately, such as connecting to the local server process ), If it's not set up right away, return , here TCP The three-way handshake continues behind , And programs can do other things , And then call select Detect non blocking connect Whether it is completed or not ( At this point, you can specify select Timeout for , This timeout can be set to a time greater than connect The timeout of is short ), If select Time out will close socket, Then you can try to create new socket Reconnect the , If select Return to non blocking socket If the descriptor is writable, the connection is established successfully , If select Return to non blocking socket If the descriptor is both readable and writable, it indicates a connection error ( Be careful : This has to be distinguished from another normal connection , After the connection is established , The server sends data to the client , here select It also returns non blocking socket Descriptors are both readable and writable , This can be distinguished by the following methods :
1. call getpeername Get the end-to-end socket Address . If getpeername return ENOTCONN, Indicates that the connection establishment failed , And then use SO_ERROR call getsockopt Get the pending error on the socket descriptor ;
2. call read, The read length is 0 Bytes of data . If read Call failed , The connection establishment failed , and read Back to errno Indicates why the connection failed . If the connection is established successfully ,read Should return to 0;
3. Call again connect. It should fail , If the error errno yes EISCONN, It means that the socket has been established , And the first connection was successful ; otherwise , The connection fails ;
For unconnected socket type (SOCK_DGRAM), The client can also call connect Connect , This connection doesn't actually create something like SOCK_STREAM The connection of , And just save the address of the opposite end locally , In this way, subsequent read-write operations can take the opposite end of the connection as the operation object by default .

When the opposite machine crash Or the network is disconnected ( For example, the router doesn't work , Disconnection of network cable, etc ), At this point, the data is sent to the opposite end, and then read Take the local end socket Returns the ETIMEDOUT perhaps EHOSTUNREACH perhaps ENETUNREACH( The last two are the cases when the intermediate router judges that the server host is unreachable ).

When the opposite machine crash after also Restart , Then the client sends data to the original connection , Because the server has no original connection information , At this point, the server sends back RST To the client , At this point the client read The local port returns ECONNRESET error .

When the process in which the server is located is closed normally or abnormally , All open file descriptors will be close, So for connected socket Descriptors are sent to the opposite end FIN The normal closing process is carried out in sections . The opposite end receives FIN Then the port becomes can read , here read Take port will return 0 At the end of the file ( The opposite end will no longer send data ).

When one end receives RST Lead to read take socket return ECONNRESET, At this point, if you call again write Sending data to the opposite end triggers SIGPIPE The signal , The signal terminates the process by default , If you ignore this signal or from SIGPIPE The signal processor of returns write Error return EPIPE.

It can be seen that only when the local port actively sends messages to the opposite end can the abnormal connection interruption be detected , collocation select When multiplexing ,socket received RST perhaps FIN When ,select return can read ( Heartbeat messages are used to detect the state of the connection ). You can also use socket Of KEEPLIVE Options , rely on socket Self detection socket The connection is broken abnormally .

send out socket Data has the following methods :

call ssize_t send(int sockfd, const void *buf, size_t nbytes, int flags);, It can only be used when the connection is established socket( Connection oriented SOCK_STREAM Or call connect Of SOCK_DGRAM).flags The values are as follows :

MSG_DONTROUTE No routing of data

MSG_DONTWAIT Don't wait for data transmission to complete

MSG_EOR End of packet

MSG_OOB Out of band data

Be careful send The successful return of the function does not mean that the peer must have received the message sent , In addition, for datagram protocol, if the data sent is larger than the length of a datagram, the sending fails (errno Set to EMSGSIZE).

linux client Socket Non blocking connect Programming ( Text )linux client Socket Non blocking connect Programming ( Text )/* Development process and source code analysis

Develop test environment : virtual machine CentOS,windows Network debugging assistant
The non blocking modes are 3 Uses

1. Shake hands three times and do other things at the same time .connect It takes a round trip to complete , From a few millisecond LAN to a few hundred millisecond or a few second wan . There may be some other processing to perform during this time , Like data preparation , Pretreatment, etc .
2. Using this technology to make multiple connections . This is in web It's very common in browsers .
3. Because the program uses select Wait for the connection to complete , You can set a select Waiting time limit , To shorten connect Timeout time . In most implementations ,connect The timeout for is 75 Between seconds and minutes . Sometimes the program wants to wait for a certain amount of time to finish , Use non blocking connect It can prevent blocking 75 second , In multithreaded network programming , Especially necessary . For example, there is one that communicates with other hosts by setting up threads socket Communication applications , If the established thread uses blocking connect And remote communication , When there are hundreds of concurrent threads , All blocked due to network delay , Blocked threads do not release system resources , When more than a certain number of threads are blocked at the same time , The system will no longer allow new threads to be created ( Each process can produce limited threads due to process space ), If you use non blocking connect, Connection failed. Use select Waiting for a short time , If it's not connected yet , The thread ends immediately and releases resources , Prevent a large number of threads from blocking and causing the program to crash .

at present connect The general idea of nonblocking programming is :
In a TCP After the socket is set to non blocking , call connect,connect It will be provided in the system errno Variable returns a EINRPOCESS error , here TCP The three-way handshake continued . It can be used later select Function to check whether the connection is established successfully . The following experiments are based on unix Network programming and general examples given on the network , After a lot of testing , There are many ways to find out , stay linux in , Not applicable .

I first give a step-by-step analysis of the important source code , At the end of the paper, the complete connect Non blocking source code .
1. First fill in the socket structure , Including remote ip, The communication ports are as follows : */
struct sockaddr_in serv_addr;
serv_addr.sin_family=AF_INET;
serv_addr.sin_port=htons(9999);
serv_addr.sin_addr.s_addr = inet_addr("58.31.231.255"); //inet_addr Convert to network byte order
bzero(&(serv_addr.sin_zero),8);

// 2. establish socket Socket :
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
perror("socket creat error");
return 1;
}

// 3. take socket Set up as non blocking , here socket Set to non blocking mode
flags = fcntl(sockfd,F_GETFL,0);// Get established sockfd Current state ( Non blocking )
fcntl(sockfd,F_SETFL,flags|O_NONBLOCK);// Will the current sockfd Set to non blocking
/*4. establish connect Connect , here socket Set to non blocking ,connect After calling , Return immediately whether the connection is established or not -1, At the same time errno( contain errno.h You can use it directly ) Set to EINPROGRESS, Indicates when tcp Three handshakes are still going on , If errno No EINPROGRESS, The connection error , Program end .
When the client and server are on the same host ,connect Go back to the horse and finish , And back to 0; No need to wait , So use goto Function skip select Wait function , Go directly to the post connection processing section .*/

if ( ( n = connect( sockfd, ( struct sockaddr *)&serv_addr , sizeof(struct sockaddr)) ) < 0 )
{
if(errno != EINPROGRESS) return 1;
}

if(n==0)
{
printf("connect completed immediately");
goto done;
}

/* 5. Set the wait time , Use select Function to wait for connect function , What needs to be explained here is the use of select monitor socket Whether the descriptor is readable or writable , If you can only write , Description connection successful , You can do the following . If the descriptor is both readable and writable , There are two cases , The first is socket There was an error connecting ( Don't ask why , It's the system , When it's readable and writable, it could be connect After successful connection, the remote host disconnected close(socket)), The second situation is connect Successful connection ,socket Read the buffer to get the data sent by the remote host . Need to pass through connect Connect and return to errno To determine , Or by calling getsockopt(sockfd,SOL_SOCKET,SO_ERROR,&error,&len); Function returns a value to determine if an error has occurred , There's a portability issue , stay solaris Error in return -1, But in other systems it is possible to return 0. I press... First unix Network programming source code to achieve . as follows :*/

FD_ZERO(&rset);
FD_SET(sockfd,&rset);
wset = rset;
tval.tv_sec = 0;
tval.tv_usec = 300000;
int error;
socklen_t len;

if(( n = select(sockfd+1, &rset, &wset, NULL,&tval)) <= 0)
{
printf("time out connect error");
close(sockfd);
return -1;
}

If ( FD_ISSET(sockfd,&rset) || FD_ISSET(sockfd,&west) )
{
len = sizeof(error);
if( getsockopt(sockfd,SOL_SOCKET,SO_ERROR,&error,&len) <0)
return 1;
}

/* Here I tested , according to unix Description of network programming , When something goes wrong on the Internet ,getsockopt return -1,return -1, Program end . The network returns when it's normal 0, Program continues .
But I'm here linux Next , Whether or not there is an error on the network ,getsockopt Always return 0, No return -1, explain linux And unix There are still some subtle differences in network programming . That is to say, when socket When descriptors are readable and writable , This code doesn't work . Can't detect if the network is down .
The way I test it is , When calling connect after ,sleep(2) Sleep 2 second , Use these two seconds to disconnect the network assistant , Now select return 2, The description socket is readable and writable , It should be an error in the network connection .
here ,getsockopt return 0, It doesn't work . obtain errno Value , The indication is EINPROGRESS, No return unix Network programming says ENOTCONN,EINPROGRESS Indicates that you are trying to connect , Cannot indicate that the network has failed to connect .
In this case ,unix Network programming puts forward another 3 Methods , this 3 Methods , It's also a common non blocking method given on the network connect Example :
a. Call again connect once . Failure to return errno yes EISCONN Description connection successful , It means just now connect success , Otherwise return to failure . The code is as follows :*/

int connect_ok;

connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(struct sockaddr) );
switch (errno)
{
case EISCONN: //connect ok
printf("connect OK \n");
connect_ok = 1;
break;
case EALREADY:
connect_0k = -1
break;
case EINPROGRESS: // is connecting, need to check again
connect_ok = -1
break;
default: 
printf("connect fail err=%d \n",errno);
connect_ok = -1;
break;
}

/* As the program shows , According to the call again errno The return value will connect_ok Value , To do the following ,connect_ok by 1 Continue with other operations , Otherwise, the program ends .
But this way I'm linux It's a test , When something goes wrong ,socket The descriptor ( My program is sockfd) Become readable and writable , But the second call connect after ,errno Did not return EISCONN,, No connection failure error was returned , It's still EINPROGRESS, And when the network doesn't break down , Use... For the second time connect The connection also returns EINPROGRESS, So it can't be passed again connect To determine if the connection is successful .
b.unix Network programming says to use read function , If you fail , Express connect Failure , Back to errno Pointed out the reason for the failure , But this method is in linux No way up ,linux stay socket When descriptors are readable and writable ,read return 0, It's not going to be errno For a mistake .
  c.unix Network programming says to use getpeername function , If the connection fails , After calling this function , adopt errno To determine whether the first connection is successful , But I tried , Whether the network connection is successful or not ,errno No change , All for EINPROGRESS, Unable to judge .
Sadness! , Even call getpeername function ,getsockopt The function still doesn't work .
To sum up, the method , Since we don't know exactly what non blocking is connect The success of , So I send it directly when the descriptor is readable and writable , Judge whether it is successful by getting the return value of the server .( If the server side design doesn't send data , That's sad .)
The writing form of the program is for portability , according to unix Network programming recommended writing , Use getsocketopt Judge , But not by the return value , And judging by the return parameters of the function .
6. use select Look at the receive descriptor , If it's readable , Just read the data , Program end . When receiving data, pay attention to the previous rset Reassign to descriptor , because select Would be right rset Zero clearing , When calling select after , If socket It doesn't become readable , be rset stay select It will be set to zero . So if you use rset, It's better to use it again rset assignment .

The procedure is as follows :*/

FD_ZERO(&rset);
FD_SET(sockfd,&rset);// If the previous select Used rset, It's better to reassign

if( ( n = select(sockfd+1,&rset,NULL, NULL,&tval)) <= 0 )
{
close(sockfd);
return -1;
}

if ((recvbytes=recv(sockfd, buf, 1024, 0)) ==-1)
{
perror("recv error!");
close(sockfd);
return 1;

}
printf("receive num %d\n",recvbytes);

printf("%s\n",buf);

*/

Non blocking connect

In a TCP The socket interface is set to call after non blocking connect,connect Will return immediately EINPROGRESS error , Indicates that the connection operation is in progress , But it's not finished yet ; meanwhile TCP The three-way handshake operation continues ; After this , We can call select To check if the link is successful ; Non blocking connect There are three uses :
1. We can do something else while shaking hands in three ways .connect The operation takes a round trip time to complete , And it can be anywhere , From a few milliseconds LAN to a few hundred milliseconds or a few seconds wan . During this time, we may have some other processing that we want to perform ;
2. You can use this technology to establish multiple connections at the same time . stay Web It's very common in browsers ;
3. Because we use select To wait for the connection to complete , So we can give select Set a time limit , To shorten connect Timeout for . In most implementations ,connect The timeout for is 75 Between seconds and minutes . Sometimes applications want a shorter timeout , Use non blocking connect It's just one way ;
Non blocking connect It sounds simple , But there are still some details to deal with :
1. Even if the socket is non blocking , If the connected server is on the same host , So in calling connect When establishing a connection , The connection is usually established immediately . We have to deal with this situation ;
2. Derived from Berkeley The implementation of the ( and Posix.1g) There are two and select And non blocking IO Relevant rules :
  A: When the connection is established successfully , The socket descriptor becomes writable ;
  B: When the connection goes wrong , Socket descriptors become both readable and writable ;
  Be careful : When a socket goes wrong , It will be select The call is marked as both readable and writable ;

Non blocking connect There are so many benefits , But dealing with non blocking connect There's a lot of portability issues that come up with ;

Handle non blocking connect Steps for :
First step : establish socket, Returns the socket descriptor ;
The second step : call fcntl Set the socket descriptor to non blocking ;
The third step : call connect Start connection ;
Step four : Determine if the connection was successfully established ;
       A: If connect return 0, The connection is successful ( This can happen when the server and client are on the same machine );
       B: call select To wait for the connection to be established ;
         If select return 0, Indicates that the connection establishment timed out ; We return the timeout error to the user , Also close the connection , To prevent the three-way handshake operation from continuing ;
         If select Return is greater than the 0 Value , You need to check whether the socket descriptor is readable or writable ; If the socket descriptor is readable or writable , Then we can call getsockopt Get the pending error on the socket (SO_ERROR), If the connection is established successfully , This error value will be 0, If you encounter an error establishing the connection , Then this value is corresponding to the connection error errno value ( such as :ECONNREFUSED,ETIMEDOUT etc. ).
" Error reading socket " It's the first portability issue that we have ; If something goes wrong ,getsockopt Derived from Berkeley The implementation of is to return 0, The error waiting to be processed is in the variable errno Back in ; however Solaris Will make getsockopt return -1,errno Set to pending error ; We have to deal with both cases ;

such , In dealing with non blocking connect when , Portability problems in different platforms of socket implementation , First , It's possible to call select Before , The connection is established , And the other side's data has arrived . under these circumstances , When the connection is successful, the socket will be both readable and writable . This is the same as when the connection fails . At this time, we have to pass getsockopt To read the error value ; This is the second portability issue ;
Summary of portability issues :
1. For the wrong socket descriptor ,getsockopt The return value of is derived from Berkeley The implementation of is to return 0, The pending error values are stored in errno in ; And from Solaris The implementation of is to return 0, The pending errors are stored in errno in ;( Called when socket descriptor error occurs getsockopt The return value of is not portable )
2. It's possible to call select Before , The connection is established , And the other side's data has arrived , under these circumstances , Socket descriptors are both readable and writable ; This is the same as when the socket descriptor goes wrong ;( How to judge whether the connection is successful is not portable )

In this case , When we judge whether the connection is successful or not, the condition is not unique , We can solve this problem in the following ways :
1. call getpeername Instead of getsockopt. If the getpeername Failure ,getpeername return ENOTCONN, Indicates that the connection establishment failed , We must use SO_ERROR call getsockopt Get the pending error on the socket descriptor ;
2. call read, The read length is 0 Bytes of data . If read Call failed , The connection establishment failed , and read Back to errno Indicates why the connection failed . If the connection is established successfully ,read Should return to 0;
3. Call again connect. It should fail , If the error errno yes EISCONN, It means that the socket has been established , And the first connection was successful ; otherwise , The connection fails ;

Interrupted connect:
If called on a blocking socket connect, stay TCP The three-way handshake operation was interrupted before it was completed , for instance , The captured signal is interrupted , What's going to happen ? Assume connect No automatic restart , It will return EINTR. that , This is the time , We can no longer call connect Wait for the connection to be established , If called again connect To wait for the connection to be established ,connect Will return an error value EADDRINUSE. under these circumstances , What should be done is to call select, It's like in non blocking connect The same thing that we did in . then ,select After the connection is established successfully ( Make socket descriptor writable ) Or connection establishment failed ( Make socket descriptors both readable and writable ) When to return to ;

Connection oriented socket Data processing and non blocking connect More articles on the question

  1. UDP socket Set to non blocking mode of

    UDP socket Set to non blocking mode of  Len = recvfrom(SocketFD, szRecvBuf, sizeof(szRecvBuf), MSG_DONTWAIT, (struct so ...

  2. linux client Socket Non blocking connect Programming

    Develop test environment : virtual machine CentOS,windows Network debugging assistant         The non blocking modes are 3 Uses         1. Shake hands three times and do other things at the same time .connect It takes a round trip to complete , From a few milliseconds of LAN to a few hundred ...

  3. be based on MFC Of socket Programming ( Asynchronous non blocking communication )

        For many beginners , Development of network communication program , A common phenomenon is that it is difficult to get started . Many concepts , Such as : Sync (Sync)/ asynchronous (Async), Blocking (Block)/ Non blocking (Unblock) etc. , Beginners are often confused , ...

  4. ( turn ) Non blocking Connect about select We should pay attention to the problems when we are working

    For connection oriented socket type (SOCK_STREAM,SOCK_SEQPACKET) A connection must be established before data can be read or written , First, the server side socket It must be monitored at an address known to the client , That is to create socket after ...

  5. UNIX Network programming - Non blocking connect And non blocking accept

    1. Non blocking connect After reading a lot of information , My own understanding is : stay socket When you initiate a connection , It takes a while to finish the three handshakes , If the network situation is not good or some other situation , This process takes a long time ...

  6. Non blocking in network programming connect To write

    One .connect Non blocking writing TCP The establishment of a connection involves a process of three handshakes , And socket in connect The function needs to wait until the customer receives a SYN Of ACK So far , This means that every individual connect Functions always ...

  7. TCP Non blocking accept And non blocking connect

    http://blog.chinaunix.net/uid-20751538-id-238260.html Non blocking accept      When a completed connection is ready to be accept When ,select I'll put you in jail ...

  8. UNIX Network programming —— Non blocking connect: Web Client procedure

    Non blocking connect The implementation example of is from Netscape Of Web Client procedure . The customer first establishes a relationship with a Web Server's HTTP Connect , Get another home page . The home page often contains multiple references to other pages . Customers can use non blocking conne ...

  9. from select/epoll Non blocking of return connect It will be EINPROGRESS State ?

    In general , We use non blocking as shown in the following code connect: #include <stdio.h> #include <stdlib.h> #include <str ...

Random recommendation

  1. 【 Code Notes 】iOS- Click on a button, Out 6 individual button

    One , design sketch . Two , Engineering drawings . 3、 ... and , Code . RootViewController.h #import <UIKit/UIKit.h> // Add header file #import "DCPathB ...

  2. sql server String function str()

    grammar : STR(nExpres[,nLength[,nDecimalPlaces]]) Parameters : nExpression------STR The numeric expression to evaluate . nLength------------ST ...

  3. Daily Scrum – 1/11

    Meeting Minutes Found a new bug, That is, when reciting too many words , There will be statistical information beyond the text box phenomenon : Updated tfs, I understand the way of packing : Burndown     Progress   part ...

  4. CXF timeout

    from : http://peak.iteye.com/blog/1285211 http://win.sy.blog.163.com/blog/static/9419718620131014385644 ...

  5. Java [Leetcode 268]Missing Number

    Title Description : Given an array containing n distinct numbers taken from 0, 1, 2, ..., n, find the one that is ...

  6. .NET Design patterns (2): singleton pattern (Singleton Pattern)

    Reprint :http://terrylee.cnblogs.com/archive/2005/12/09/293509.html singleton pattern (Singleton Pattern) --.NET Design pattern series 2 ...

  7. Netease cloud classroom _ Introduction to programming -C Language _ In the second week of : Judge _2 Signal report

    2 Signal report (5 branch ) Topic content : The radio station's RS The signaling report is made up of three or two parts : R(Readability) Signal resolution is clarity . S(Strength)     Signal strength is size . among R At the top of the report ...

  8. hdu1711 Number Sequence

    Problem Description Given two sequences of numbers : a[1], a[2], ...... , a[N], and b[1], b[2], .... ...

  9. 【WebGL】《WebGL Programming Guide 》 Reading notes —— The first 2 Chapter

    One . Preface Recently saw <WebGL Programming Guide > This book , It's interesting to find out , So take notes after reading each chapter . Two . Text Example1: stay canvas Draw a rectangle in <!DOCTYPE html> ...

  10. Algorithm exercises LeetCode Sorting and searching of primary algorithms

    Merge two ordered arrays class Solution { public void merge(int[] nums1, int m, int[] nums2, int n) { System.arrayco ...