socket error 10057问题 _错误记录

来源:互联网 发布:unity3d 第三人称射击 编辑:程序博客网 时间:2024/06/03 23:39

10057 是socket is not connected,后来发现之前套接字设置成非阻塞,connect 尝试连接时连接不通立即返回,此时TCP还在三次握手,所以要写成非阻塞connect限时模式,让select函数检查是否成功连接,并设置超时检测功能。

另外注意两点移植


问题:1.getsockopt源自Berkeley的实现是返回0,等待处理的错误在变量errno中返回;但是Solaris会让getsockopt返回-1,errno置为待处理的错误;我们对这两种情况都要处理;

2.在处理非阻塞connect时,在不同的套接口实现的平台中存在的移植性问题,首先,有可能在调用select之前,连接就已经建立成功,而且对方的数据已经到来.在这种情况下,连接成功时套接口将既可读又可写.这和连接失败时是一样的.这个时候我们还得通过getsockopt来读取错误值


简单代码如下,仅供参考:

BOOL  ConnectServer(int robot_num)
{
char errnum[10] = {0};
int err = -1;
int error = -1;
int errlen = sizeof(error);
int no1 = robot_num;
fd_set wset;
struct timeval tm;
tm.tv_sec = 5;
tm.tv_usec = 0;
FD_ZERO(&wset);
FD_SET(sHost[no1],&wset);


//设置服务器地址
servAddr.sin_family =AF_INET;
servAddr.sin_addr.s_addr = inet_addr("192.168.1.104");//&ip[no1-1][0]    
servAddr.sin_port = htons(6665);//atoi(&port[no1-1][0])    

//连接服务器

retVal=connect(sHost[no1],(LPSOCKADDR)&servAddr, sizeof(servAddr));
err = WSAGetLastError();

if(SOCKET_ERROR == retVal)
{
if( WSAEWOULDBLOCK == err || WSAEINVAL == err) //无法立即完成非阻塞的操作
{
if(select(0,NULL,&wset,NULL,&tm) <= 0){    //此处错误超时 或者 连接不上;返回0,代表超时
printf("error code is %s\n",strerror(errno));
closesocket(sHost[no1]);
}
if( !FD_ISSET(sHost[no1],&wset)){   //若是集合里的值,非零;
printf("error code is %s\n",strerror(errno));
closesocket(sHost[no1]);
}
getsockopt(sHost[no1],SOL_SOCKET,SO_ERROR,(char*)&error,&errlen);
if (error != 0)
{
printf("Connect failed!\n");
bConnecting = FALSE;
}else{
printf("Connect successfully!\n");
bConnecting = TRUE;
}
}else if (WSAEISCONN == err)//连接已经完成
{
printf("连接已经完成 \n");

}else if (WSAENOTCONN == err)//连接没有完成
{
printf("socket is not connected \n");

}else//其它原因,连接失败
{
printf("connect err =%d\n",err);  //在非阻塞套接字上尝试一个已经正在进行的操作
printf("其它原因,连接失败\n");
}
}


if ( retVal == 0 )//连接成功
{
printf("Connect successfully!\n");
bConnecting = TRUE;
}
return bConnecting;
}

原创粉丝点击