非阻塞Socket连接处理

非阻塞套接字,connect不能立即完成就会返回错误,一般情况下会在系统提供的errno变量中返回一个EINRPOCESS错误,此时TCP的三路握手继续进行。那如何判断connnect的连接是否成功完成呢?从网络查看了很多相关文章,linux系统中没有对这个问题提供很好的处理方法,大多做法都是通过程序逻辑判断,逻辑过程如下:
1.建立socket
2.将该socket设置为非阻塞模式
3.调用connect()
4.使用select()检查该socket描述符是否可写(注意,是可写)
5.根据select()返回的结果判断connect()结果

#include <sys/socket.h>
#include <sys/types.h>
#define TIME_OUT_TIME 30
int main(int argc , char **argv)
{
	int sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if(sockfd < 0) 
		exit(1);

	struct sockaddr_in serv_addr;
	int error = -1;
	int len = sizeof(int);
	timeval tm;
	fd_set set;
	unsigned long ul = 1;

	//设置为非阻塞模式
	ioctl(sockfd, FIONBIO, &ul);
	bool ret = false;
	if( connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) == -1)
	{
		tm.tv_set  = TIME_OUT_TIME;
		tm.tv_uset = 0;
		FD_ZERO(&set);
		FD_SET(sockfd, &set);
		//只处理可写的情况,可读和异常都设置为NULL,并设置超时时间为30
		if(select(sockfd+1, NULL, &set, NULL, &tm) > 0)
		{
			//这里需要使用getsockopt函数来获取套接口目前的一些信息来判断是否真的是连接上了
			getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, (socklen_t *)&len);
			if(error == 0) {
				ret = true;
			} else { 
				ret = false;
			}
		} else { 
			ret = false;
		}
	} else {
		ret = true;
	}
	
	if(!ret) 
	{
		close( sockfd );
		fprintf(stderr , "Cannot Connect the server!/n");
		return;
	}
	
	fprintf( stderr , "Connected!/n");
}



   

你可能感兴趣的:(编程,struct,网络,socket,server)