socket error 10057问题 _错误记录

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;
}

`NETCONN_EVT_ERROR` 并不是一个具体的错误类型,而是表示在网络连接过程中发生了某种异常情况或错误事件的一个标识符。它通常是某个枚举类型 (`enum`) 中的一个值,例如在 lwIP 网络协议栈中可能会有类似如下的定义: ```c typedef enum { NETCONN_EVT_SENDPLUS, NETCONN_EVT_RECVPLUS, NETCONN_EVT_DONE, NETCONN_EVT_ERROR, // 错误事件标志位 ... } netconn_evt_t; ``` 当 `NETCONN_EVT_ERROR` 被触发时,意味着当前的网络操作遇到了不可预期的情况或者失败了。比如,在 TCP 链接建立、数据发送/接收等环节出现问题时,就会通知上层应用存在错误。 不过需要注意的是,“具体”的错误原因并不会通过该标记本身体现出来;如果需要了解更详细的信息,则一般会结合其他机制一同使用,像检查返回码、读取系统级错误描述(errno)、查看日志记录等方式进一步定位问题所在。 --- ### 示例场景说明 假设我们正在开发一款基于 lwIP 协议栈的应用程序,并设置了自定义回调函数来监听所有可能影响正常运行的状态变化: 1. **初始化阶段** - 尝试创建一个新的 socket 或者发起三次握手建链请求; - 若目标主机不存在、端口关闭等原因导致无法完成上述动作,那么最终都会向用户反馈此类“error”消息。 2. **传输期间** - 正常的数据交互当中也可能遭遇中断现象; - 比方说远端突然断开了链接 (RST 包),此时也会激活对应 handler 内部预设好的分支逻辑——也就是我们的主题提到的那个 case 分支。 总之,`NETCONN_EVT_ERROR` 提供了一种高层次的通知手段,告诉开发者:“嘿,出状况啦,请尽快查清楚到底哪里出了差错吧!”
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值