Document directory
In highly concurrent network programming, if the socket timeout is not controlled, the program will die very hard.
Here, the timeout time must be controlled in three parts: Connection timeout, read timeout, and write timeout.
The preceding timeout problems are solved in sequence.
Connection timeout processing there are several methods for connection timeout. The first method is trick,
Use the properties of the socket to set. This attribute can be set because the connect kernel implementation (source file address) adopts the following implementation method:
/** Connect to a remote host. there is regrettably still a little * TCP 'Magic 'in here. */INT _ inet_stream_connect (struct socket * sock, struct sockaddr * uaddr, int addr_len, int flags) {// omitting the previous Code timeo = sock_sndtimeo (sk, flags & o_nonblock); If (1 <SK-> sk_state) & (tcpf_syn_sent | tcpf_syn_recv) {int writebias = (SK-> sk_protocol = ipproto_tcp) & tcp_sk (SK)-> fastopen_req & tcp_sk (SK)-> Fastopen_req-> data? 1: 0;/* error code is set above */If (! Timeo |! Inet_wait_for_connect (SK, timeo, writebias) goto out; err = sock_intr_errno (timeo); If (signal_pending (current) goto out ;} // Code omitted} export_symbol (_ inet_stream_connect );
This function uses the socket sending timeout settings.
Therefore, when you control the connection timeout, you can use the following code to set the socket sending timeout. The specific process can be described as follows:
- Create socket
- Use the setsockopt function to set specific socket settings. Set the sending timeout here.
- Use connect to perform the connection operation.
The Code is as follows:
int sock_fd = socket(AF_INET, SOCK_STREAM, 0); if (sock_fd < 0) { perror("create sock_fd"); exit(-1); } struct sockaddr_in addr; bzero(&addr,sizeof(addr)); addr.sin_family = AF_INET; addr.sin_port=htons(g_conf.aod_port); addr.sin_addr.s_addr = inet_addr(g_conf.aod_host); struct timeval timeo = {0, 0}; socklen_t len = sizeof(timeo); timeo.tv_usec = 10*1000;//10ms setsockopt(sock_fd, SOL_SOCKET, SO_SNDTIMEO, &timeo, len); if(connect(sock_fd, (sockaddr*)&addr,sizeof(addr))<0){ fprintf(,stdout,"%s","CONNECT WITH AOD SERVER FAILED"); return -1; }
Another method for timeout setting for connect is to use the select/poll method widely circulated on the Internet. This method comes from Manuel of the connect function. Using man connect, you can see the following description of the return value of the connect function:
EINPROGRESS The socket is non-blocking and the connection cannot be completed immediately. It is possible to select(2) or poll(2) for completion by selecting the socket for writing. After select(2) indicates writability, use getsock- opt(2) to read the SO_ERROR option at level SOL_SOCKET to determine whether connect() completed successfully (SO_ERROR is zero) or unsuccessfully (SO_ERROR is one of the usual error codes listed here, explaining the rea- son for the failure).
Based on the above description, we can use the return value of connect to make some articles to complete the settings of connect. In fact, the above manual has given a basic step to implement the connect timeout setting. This method is more complex than the previous method:
- Create a socket file descriptor
- Set the socket to a non-blocking connection mode
- Call the connect function to determine the return value of connect.
- Use select to check whether the file descriptor of the socket is writable.
- Reset socket to blocking mode