C++ WinSock2 等待客户端发送数据
C++ WinSock2 wait until client sends data
我有一个多线程套接字服务器,它应该与客户端进行连续对话,所以我将我的 recv
放在 while(true)
中以保持连接,直到双方关闭它。我遇到的问题是当客户端没有发送任何东西时,服务器一直在尝试接收数据,这最终导致它崩溃,因为它什么也没有读取,所以我想知道是否有办法让 recv
停止直到有实际数据接收。
这是处理客户端连接的函数的代码:
void Communicator::clientHandler(SOCKET client)
{
try
{
while (true)
{
char codeBuff[1];
recv(client, codeBuff, 1, 0);
int code = static_cast<int>(static_cast<unsigned char>(codeBuff[0]));
char lengthBuff[4];
recv(client, lengthBuff, 4, 0);
int dataLength = lengthBuff[0] << 24 | lengthBuff[1] << 16 | lengthBuff[2] << 8 | lengthBuff[3];
char* dataBuff = new char(dataLength);
recv(client, dataBuff, dataLength, 0);
dataBuff[dataLength - 1] = 0;
std::vector<char> dataVec(dataBuff, dataBuff + dataLength);
Request r = {
code,
std::time(nullptr),
dataVec
};
std::copy(dataVec.begin(), dataVec.end(), std::ostream_iterator<char>(std::cout, "")); // For debug purposes, prints infintiely
IRequestHandler* handler = nullptr;
{
std::lock_guard<std::mutex> locker(m_clientsMu);
handler = m_clients.find(client)->second;
}
if (handler->isRequestRelevant(r))
{
RequestResult res = handler->handleRequest(r);
{
std::lock_guard<std::mutex> locker(m_clientsMu);
delete[] m_clients.find(client)->second;
m_clients.find(client)->second = res.newHandler;
}
send(client, &res.response[0], res.response.size(), 0);
}
else
{
ErrorResponse res = { "Invalid request type" };
std::vector<char> packet = JsonPacketSerializer::serializeResponse(res);
send(client, &packet[0], packet.size(), 0);
}
}
}
catch (...)
{
closesocket(client);
throw;
}
}
我用来测试服务器的一些基本 python 代码:
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_TCP)
s.connect(('127.0.0.1', 8080))
s.send(bytes([101, 0, 0, 0, 40, 123, 34, 112, 97, 115, 115, 119, 111, 114, 100, 34, 58, 34, 49, 50, 51, 52, 53, 54, 34,
44, 34, 117, 115, 101, 114, 110, 97, 109, 101, 34, 58, 34, 116, 101, 115, 116, 34, 125]))
msg = s.recv(1024)
print(msg)
char* dataBuff = new char(dataLength);
这会创建 one char
,最有可能的值是 dataLength & 255
,而 dataBuff
将指向 一个char
。你像这样分配一个 char
的数组:
char* dataBuff = new char[dataLength];
您还必须稍后释放内存:
delete[] dataBuff;
您还需要注意 recv
中的 return 值,这是接收到的字节数(或 SOCKET_ERROR
表示错误)。
我有一个多线程套接字服务器,它应该与客户端进行连续对话,所以我将我的 recv
放在 while(true)
中以保持连接,直到双方关闭它。我遇到的问题是当客户端没有发送任何东西时,服务器一直在尝试接收数据,这最终导致它崩溃,因为它什么也没有读取,所以我想知道是否有办法让 recv
停止直到有实际数据接收。
这是处理客户端连接的函数的代码:
void Communicator::clientHandler(SOCKET client)
{
try
{
while (true)
{
char codeBuff[1];
recv(client, codeBuff, 1, 0);
int code = static_cast<int>(static_cast<unsigned char>(codeBuff[0]));
char lengthBuff[4];
recv(client, lengthBuff, 4, 0);
int dataLength = lengthBuff[0] << 24 | lengthBuff[1] << 16 | lengthBuff[2] << 8 | lengthBuff[3];
char* dataBuff = new char(dataLength);
recv(client, dataBuff, dataLength, 0);
dataBuff[dataLength - 1] = 0;
std::vector<char> dataVec(dataBuff, dataBuff + dataLength);
Request r = {
code,
std::time(nullptr),
dataVec
};
std::copy(dataVec.begin(), dataVec.end(), std::ostream_iterator<char>(std::cout, "")); // For debug purposes, prints infintiely
IRequestHandler* handler = nullptr;
{
std::lock_guard<std::mutex> locker(m_clientsMu);
handler = m_clients.find(client)->second;
}
if (handler->isRequestRelevant(r))
{
RequestResult res = handler->handleRequest(r);
{
std::lock_guard<std::mutex> locker(m_clientsMu);
delete[] m_clients.find(client)->second;
m_clients.find(client)->second = res.newHandler;
}
send(client, &res.response[0], res.response.size(), 0);
}
else
{
ErrorResponse res = { "Invalid request type" };
std::vector<char> packet = JsonPacketSerializer::serializeResponse(res);
send(client, &packet[0], packet.size(), 0);
}
}
}
catch (...)
{
closesocket(client);
throw;
}
}
我用来测试服务器的一些基本 python 代码:
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_TCP)
s.connect(('127.0.0.1', 8080))
s.send(bytes([101, 0, 0, 0, 40, 123, 34, 112, 97, 115, 115, 119, 111, 114, 100, 34, 58, 34, 49, 50, 51, 52, 53, 54, 34,
44, 34, 117, 115, 101, 114, 110, 97, 109, 101, 34, 58, 34, 116, 101, 115, 116, 34, 125]))
msg = s.recv(1024)
print(msg)
char* dataBuff = new char(dataLength);
这会创建 one char
,最有可能的值是 dataLength & 255
,而 dataBuff
将指向 一个char
。你像这样分配一个 char
的数组:
char* dataBuff = new char[dataLength];
您还必须稍后释放内存:
delete[] dataBuff;
您还需要注意 recv
中的 return 值,这是接收到的字节数(或 SOCKET_ERROR
表示错误)。