我制作了一个简单的客户端服务器程序,但主要问题是,一旦客户端和服务器之间建立连接,如果客户端关闭程序,服务器会重复执行最后一条消息,有时会产生巨大的问题。所以我想要的是是否有任何函数可以调用来获取 SOCKET 结构的状态,这样如果客户端关闭程序,服务器就会知道停止。我只需要从函数中查找错误套接字的功能。顺便说一句,我正在用 Win32 c 编写这个程序。我尝试了 if(mySocket==SOCKET_ERROR) ,它似乎不起作用......除非我使用错误。我刚刚开始网络。
if(!sockServer.RecvData( recMessage, STRLEN )){return 0;}
// where
bool Socket::RecvData( char *buffer, int size )
{
int i = recv( mySocket, buffer, size, 0 );
if(!i){return false;}
buffer[i] = '\0';
return true;
} //this isn't working
如果对等方关闭套接字,
read()
和recv()
将返回零。您必须忽略,如果“服务器重复执行最后一条消息”,这当然会“造成巨大的问题”,不仅仅是“有时”,而且总是。
编辑1:您还犯了另一个基本的TCP编程错误:您假设您在一次读取中收到了完整的消息。 TCP 中没有消息,只是字节流,写入和读取之间没有 1::1 对应关系(
send()
和 recv()
)。 recv()
可以返回零或少至 1 个字节。您必须组织自己的消息边界,并且必须循环直到收到可以处理的完整消息。
编辑2:您还忽略了接收方法中的所有错误。您必须寻找
recv()
返回 -1
,而不是继续处理您尝试读取的数据的逻辑。至少您应该致电 perror()
或检查 errno
或在 Winsock WSAGetLastError()
中。
当你收到错误或 EOS 时,你必须停止循环,关闭套接字,忘记连接,并忘记这个客户端。
在主消息过程中监听 FD_CLOSE 怎么样?您正在将 WSAAsyncSelect 与 FD_CLOSE 一起使用吗?