带有 winsock 的简单 C++ 服务器-客户端应用程序
Posted
技术标签:
【中文标题】带有 winsock 的简单 C++ 服务器-客户端应用程序【英文标题】:Simple C++ server-client application with winsock 【发布时间】:2013-03-07 19:50:28 【问题描述】:我正在尝试编写一个简单的服务器-客户端应用程序,它所要做的就是: 客户端连接到服务器,服务器等待消息,客户端从用户那里获取输入,并将其发送到服务器。服务器收到此消息,并将其发送回客户端,客户端打印消息并循环并重新开始。 但是,由于某种原因,我遇到了一个相当奇怪的问题:当我发送第一条消息时,服务器会响应它,当我发送第二条消息时,服务器会再次响应第一条消息。当我发送第三条消息时,服务器会回复第二条消息,依此类推。
这是我处理连接的服务器代码:
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;
【问题讨论】:
可能是 'cin' 而不是套接字的问题?缓冲输入不会做奇怪的事情吗? 服务器代码中if
后面不是少了一个花括号吗?
不,刚刚检查过。好像没有。
在 cin 后面加了一个 cout,看起来不是问题。
是的,您在此处发布的HandleConnections
函数中缺少
。
【参考方案1】:
[TCP] 套接字编程的经验法则 - 计算字节数。这意味着实际上要注意从send(2)
和recv(2)
返回的值。它们分别告诉您从网络发送和填充了多少缓冲区。
UDP 的情况有点不同,但这在这里可能并不重要。
【讨论】:
特别是,一个 200 字节的send
可以在另一端以几个更小的块“recv”。【参考方案2】:
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
如果您有兴趣学习如何构建异步操作,您应该研究前摄器设计模式。
【讨论】:
都是正确的,但对于这个简单的案例来说太过分了【参考方案3】:我同意尼古拉的观点。记录返回的字节数很重要。此外,将默认 else 子句更改为以 recv() 的返回值为条件。
您的编译器是否将 NULL 定义为零?将 recv 函数中的 arg 也更改为零可能会更安全。
您还可以考虑在复制到发送缓冲区后修改/归零您的接收缓冲区。 (出于可追溯性目的)
【讨论】:
以上是关于带有 winsock 的简单 C++ 服务器-客户端应用程序的主要内容,如果未能解决你的问题,请参考以下文章
Winsock - 从 C++ 中的 Java 客户端读取整数
带有 winsock 和 std::thread 的 C++ 多线程服务器