简单的c++服务器-客户端应用程序与winsock

Simple C++ server-client application with winsock

本文关键字:应用程序 winsock 客户端 c++ 服务器 简单      更新时间:2023-10-16

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

下面是处理连接的服务器代码:
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;
}

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

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

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

你可以在这里找到:

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

如果您对学习如何构建异步操作感兴趣,您应该研究一下actor设计模式。

我同意Nikolai的观点。记录返回的字节数很重要。此外,将默认的else子句更改为根据recv()的返回值设置条件。

你的编译器定义NULL为零吗?如果将recv函数中的参数也改为0,可能会更安全。

你也可以考虑在复制发送缓冲区后修改/置零你的接收缓冲区。(为了便于追溯)