我在Windows上用C ++编写服务器。在连接时,服务器创建两个线程来处理请求 - 一个不断地从套接字读取输入,第二个不断地将输出写入它。我遇到了问题,因为当没有来自客户端的输入但输出发送给它时,线程#1阻塞了recv(),在send()上创建了两个块,而没有写入它的数据。
有没有办法发送()到套接字虽然它已经在阻塞recv()?
由于
编辑:
我拿出相关代码并转载了这个问题。如果我将AfxThreadCall注释掉readThread,则会发送数据。否则不是。客户端是一个简单的客户端,可以打印收到的内容。
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();
}