在windows中从同一套接字同时读写 我在Windows上用C++编写服务器。在连接时,服务器创建两个线程来处理请求——一个线程不断地从套接字读取输入,另一个线程不断地向套接字写入输出。我在使用它时遇到了问题,因为当没有来自客户端的输入但要发送到它的输出时,线程1在recv上阻塞,使得线程2在发送时阻塞,而不写入它的数据
有没有一种方法可以发送到一个套接字,尽管它已经在阻塞recv中 谢谢 编辑: 我拿出相关代码,复制了这个问题。如果我注释掉对readThread的afxthread调用,则数据将被发送。否则就不是了。客户端是一个简单的客户端,它打印接收到的内容在windows中从同一套接字同时读写 我在Windows上用C++编写服务器。在连接时,服务器创建两个线程来处理请求——一个线程不断地从套接字读取输入,另一个线程不断地向套接字写入输出。我在使用它时遇到了问题,因为当没有来自客户端的输入但要发送到它的输出时,线程1在recv上阻塞,使得线程2在发送时阻塞,而不写入它的数据,c++,windows,sockets,send,recv,C++,Windows,Sockets,Send,Recv,有没有一种方法可以发送到一个套接字,尽管它已经在阻塞recv中 谢谢 编辑: 我拿出相关代码,复制了这个问题。如果我注释掉对readThread的afxthread调用,则数据将被发送。否则就不是了。客户端是一个简单的客户端,它打印接收到的内容 SOCKET m_sockIOSrv = NULL; SOCKET m_sockIO = NULL; UINT readThread(LPVOID args) { WSABUF DataBuf; DWORD RecvBytes;
SOCKET m_sockIOSrv = NULL;
SOCKET m_sockIO = NULL;
UINT readThread(LPVOID args)
{
WSABUF DataBuf;
DWORD RecvBytes;
DWORD Flags = 0 ;
char buf[4096];
DataBuf.len = 4096;
DataBuf.buf = buf;
while (true)
{
int ret = WSARecv(m_sockIO, &DataBuf, 1, &RecvBytes, &Flags, NULL, NULL); // Read some data...
if (ret == SOCKET_ERROR)
{
printf("ERROR: WSARecv: %d", WSAGetLastError());
return 1;
}
printf("jobleader - got %d from recv\n", RecvBytes);
}
return 0;
}
UINT writeThread(LPVOID args)
{
WSABUF DataBuf;
DWORD SendBytes;
DWORD Flags;
char buf[] = { 'a', 'a', 'a' };
DataBuf.len = 3;
DataBuf.buf = buf;
while (true)
{
DWORD dwWritten;
WSASend(m_sockIO, &DataBuf, 1, &dwWritten, 0, NULL, NULL);
}
return 0;
}
SOCKET ServerSocket(unsigned int & port) {
// Our server socket
SOCKET s = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0);
if (s == INVALID_SOCKET)
return s;
SOCKADDR sa;
sa.sa_family = AF_INET;
memset(sa.sa_data, 0, sizeof(sa.sa_data));
if (bind(s, &sa, sizeof(sa))) {
closesocket(s);
return INVALID_SOCKET;
}
struct sockaddr_in sa_in;
int sz = sizeof(sa_in);
if (getsockname(s, (struct sockaddr *)&sa_in, &sz)) {
closesocket(s);
return INVALID_SOCKET;
}
if (listen(s, 50)) {
closesocket(s);
return INVALID_SOCKET;
}
port = ntohs(sa_in.sin_port);
return s;
}
int _tmain(int argc, _TCHAR* argv[])
{
unsigned int ioPort = 0;
WORD wVersionRequested = MAKEWORD(2, 2);
WSADATA wsaData;
if (WSAStartup(wVersionRequested, &wsaData))
{
if (!AfxSocketInit())
{
printf("ERROR: Unable to initialize WinSock DLL");
exit(2);
}
}
m_sockIOSrv = ServerSocket(ioPort);
if (m_sockIOSrv == INVALID_SOCKET) {
int lastError = GetLastError();
printf("ERROR: StartIOSockets Failed to start socket %d.\n",lastError);
return 1;
}
printf("Listening on %d\n", ioPort);
m_sockIO = accept(m_sockIOSrv, NULL, NULL);
AfxBeginThread(&readThread, (LPVOID)NULL);
AfxBeginThread(&writeThread, (LPVOID)NULL);
getchar();
}
你不能在recv上使用MSG_DONTWAIT标志,这样它就不会阻塞吗?@dietbacon否,因为它会让我忙着在套接字和cosume cpu上无需任何费用地一直等待。你发送数据而不请求吗?是的,这段代码的主要用途是作为远程用户和子进程之间的代理。用户在套接字上发送进程的STDIN并接收STDOUT。我不知道用户何时会发送输入,所以我只能从套接字constatly读取。我只在子进程产生输出时才向它写入数据,但由于recv阻塞,它会被卡住。我可以使用两个不同的套接字,但是客户端代码已经存在,linux代码工作正常,这是唯一一个出现问题的windows。我不想在windows上处理太多现有代码。windows中的正确解决方案是使用异步I/O,但这可能会使与Linux实现共享代码变得困难。也许选择会奏效?