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

时间:2013-03-07 19:50:28

标签: c++ sockets client-server winsock

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

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

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

3 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分: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

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

答案 2 :(得分:0)

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

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

您可能还会考虑在复制到发送缓冲区后修改/清零接收缓冲区。 (用于追踪能力)