This article is senlie original, reproduced Please retain this address: http://blog.csdn.net/zhengsenlie
/**
* TCP: use non-blocking connect
**/
# Include "unp. H"
Int
Connect_nonb (INT sockfd, const Sa * saptr, socklen_t Salen, int nsec)
{
Int flags, N, error;
Socklen_t Len;
Fd_set rset, Wset;
Struct timevaltval;
// 1. Call fcntl to set the socket to non-blocking
Flags = fcntl (sockfd, f_getfl, 0 );
Fcntl (sockfd, f_setfl, flags | o_nonblock );
// 2. Initiate a non-blocking connection
// The expected error is einprogress, indicating that the connection has been established but has not been completed.
// N> 0
Error = 0;
If (n = connect (sockfd, saptr, salen) <0)
If (errno! = Einprogress)
Return (-1 );
/* You can do other things during connection establishment */
// 3. Check whether the connection is established
// N = 0 indicates that the connection has been established (this situation is more likely to happen when the customer and the server are on the same host)
If (n = 0)
Goto done;/* connection established */
// 4. Call select
Fd_zero (& rset); // clears rset
Fd_set (sockfd, & rset); // enable the FD bit in rset
Wset = rset; // copy rset to Wset
Tval. TV _sec = nsec; // set the timeout value.
Tval. TV _usec = 0;
// Call select to wait for the socket to become readable or writable
If (n = select (sockfd + 1, & rset, & Wset, null,
Nsec? & Tval: NULL) = 0 ){
// Processing timeout. If select returns 0, the timeout occurs.
Close (sockfd );
Errno = etimedout;
Return (-1 );
}
// 5. Check readable or writable Conditions
// If the socket is writable and unreadable, the connection is established successfully.
// If the socket is writable and readable, the socket may have been successfully established before Select, or the connection fails to be established.
// If the socket is neither writable nor readable, the SELECT statement fails because sockfd is not set.
If (fd_isset (sockfd, & rset) | fd_isset (sockfd, & Wset )){
Len = sizeof (error );
// Use getsockopt to get the socket's pending error. If the connection is successfully established, the value is 0.
If (getsockopt (sockfd, sol_socket, so_error, & error, & Len) <0)
Return (-1);/* Solaris pending Error */
} Else
Err_quit ("select error: sockfd not set ");
// 6. Disable the non-blocking status and return
Done:
Fcntl (sockfd, f_setfl, flags); // restores the File status flag of the socket and returns
If (error ){
Close (sockfd);/* Just In Case */
Errno = error;
Return (-1 );
}
Return (0 );
}
# Include "unp. H"
Int
Main (INT argc, char ** argv)
{
Int sockfd, N;
Char recvline [maxline + 1];
Struct sockaddr_inservaddr;
If (argc! = 2)
Err_quit ("Usage: A. Out <IPaddress> ");
If (sockfd = socket (af_inet, sock_stream, 0) <0)
Err_sys ("socket error ");
Bzero (& servaddr, sizeof (servaddr ));
Servaddr. sin_family = af_inet;
Servaddr. sin_port = htons (13 );
If (inet_ton (af_inet, argv [1], & servaddr. sin_addr) <= 0)
Err_quit ("inet_ton error for % s", argv [1]);
// Change from connect to connect_nonb.
If (connect_nonb (sockfd, (Sa *) & servaddr, sizeof (servaddr) <0)
Err_sys ("Connect error ");
While (n = read (sockfd, recvline, maxline)> 0 ){
Recvline [N] = 0;/* null terminate */
If (fputs (recvline, stdout) = EOF)
Err_sys ("fputs error ");
}
If (n <0)
Err_sys ("read error ");
Exit (0 );
}
Time Acquisition Program client TCP use non-blocking connect