0

我正在尝试编写一个简单的服务器-客户端应用程序,它应该做的是:客户端连接到服务器,服务器等待消息,客户端从用户那里获取输入,并将其发送到服务器。服务器收到此消息,并将其发送回客户端,客户端打印消息并循环并重新开始。但是,由于某种原因,我遇到了一个相当奇怪的问题:当我发送第一条消息时,服务器会响应它,当我发送第二条消息时,服务器会再次响应第一条消息。当我发送第三条消息时,服务器会响应第二条消息,依此类推。

这是我处理连接的服务器代码:

class themusers {
    char ReMessage[200],SeMessage[200];

public:
    void * HandleConnections(SOCKET connector,int location) {

    std::string Converter;

        for (;;) {

        if (recv(connector,ReMessage,sizeof(ReMessage),NULL) == -1)
            std::cout << "Disconnected." << std::endl;
            discon.lock();
            sock_connection[location] = NULL;
            discon.unlock();
            break;
        }


        else {
                   //this is the code that handles the receive/send operation
            msgmut.lock();
            //std:: cout << ReMessage << std::endl;
            memcpy(SeMessage, ReMessage, sizeof(ReMessage));
            send(connector, SeMessage, sizeof(SeMessage), NULL);
            msgmut.unlock();        
        }

        }


        return NULL;
        }
};

这是我的客户代码:

for (;;) {
    cin >> tell;
    send(sock, tell, sizeof(tell), NULL);
    recv(sock,Message,sizeof(Message),NULL);
    Converter = Message;
    cout << "Server: " << Converter << endl;
}
4

3 回答 3

1

[TCP] 套接字编程的经验法则 -计算你的字节数。这意味着实际上要注意从send(2)and返回的值recv(2)。它们分别告诉您从网络发送和填充了多少缓冲区。

UDP 的情况有点不同,但这在这里可能并不重要。

于 2013-03-07T20:04:23.027 回答
0

Boost ASIO 是一个非常好的 C++ 库,用于实现同步和异步操作的网络和套接字 i/o 使用。

你可以在这里找到它:

http://www.boost.org/doc/libs/1_53_0/doc/html/boost_asio.html

他们还提供了一些示例,这些示例说明了为聊天服务器实现库以及其他用途:

http://www.boost.org/doc/libs/1_53_0/doc/html/boost_asio/examples.html

如果您有兴趣学习如何构建异步操作,您应该研究前摄器设计模式。

于 2013-03-07T20:21:23.357 回答
0

我同意尼古拉的观点。记录返回的字节数很重要。此外,将默认 else 子句更改为以 recv() 的返回值为条件。

您的编译器是否将 NULL 定义为零?将 recv 函数中的 arg 也更改为零可能会更安全。

您也可以考虑在复制到发送缓冲区后修改/归零您的接收缓冲区。(出于可追溯性目的)

于 2013-03-07T20:22:13.710 回答