2

我有一个简单的客户端服务器程序,但主要问题是一旦客户端和服务器之间建立连接,如果客户端关闭程序,服务器会重复执行最后一条消息,有时会产生巨大的问题。所以我想要的是,如果我可以调用任何函数来获取 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
4

2 回答 2

3

如果对等端关闭套接字,read()并且recv()将返回零。您必须忽略如果“服务器重复执行最后一条消息”,这当然会“产生巨大的问题”,而不仅仅是“有时”而是总是

编辑 1:您还犯了另一个基本的 TCP 编程错误:您假设您在一次读取中收到了整个消息。TCP 中没有消息,它只是一个字节流,写入和读取(send()recv())之间没有 1::1 的对应关系。recv()可以返回零或少至 1 个字节。您必须组织自己的消息边界,并且必须循环直到收到可以处理的完整消息。

编辑 2:您还忽略了接收方法中的所有错误。您必须寻找recv()返回 -1`,而不是继续处理您尝试读取的数据的逻辑。至少您应该调用 perror() 或检查 errno 或 Winsock 等效项。

当您收到错误或 EOS 时,您必须停止循环、关闭套接字、忘记连接并忘记此客户端。

于 2012-10-16T23:31:52.817 回答
1

在主消息过程中监听 FD_CLOSE 怎么样?您正在使用带有 FD_CLOSE 的 WSAAsyncSelect 吗?

于 2012-10-16T23:45:49.280 回答