问题描述
我创建了两个 win32 服务器 C++ 项目,它们都将执行类似的任务,例如侦听来自客户端的 IPC 连接。两者都将侦听不同的端口号,例如 1000 和 2000,我可以连接第一个启动的应用程序,例如 1000 或 2000,但不能同时连接,每隔一个连接请求就会在客户端超时。
下面我添加了我的客户端和服务器代码,我有两个端口号不同(1000 和 2000)的服务器应用程序和两个连接到 1000 和 2000 端口服务器应用程序的客户端应用程序。
两个服务器应用程序都将进入侦听模式,但一个只接受连接请求,另一个将在客户端应用程序中引发超时。如果有任何建议,请更新您的意见。
客户代码:
void Initialize()
{
WSADATA WSAData;
WSAStartup(MAKEWORD(2,2),&WSAData);
}
SOCKET CloseSocket(SOCKET _Socket)
{
/*A shutdown() closes SOCK_STREAM sockets gracefully. Both processes can ackNowledge that they are no longer sending. OR disable sends and/or receives on a socket*/
shutdown(_Socket,SD_BOTH);
/*The closesocket function closes an existing socket.*/
closesocket(_Socket);
return _Socket = INVALID_SOCKET;
}
SOCKET Connect( SOCKET _Socket,SOCKADDR_IN _Addres )
{
int connectResult = connect(_Socket,(struct sockaddr *)&_Addres,sizeof(_Addres));
if(connectResult == SOCKET_ERROR)
{
_Socket = CloseSocket(_Socket);
}
else if(connectResult == ETIMEDOUT)
{
_Socket = CloseSocket(_Socket);
}
return _Socket;
}
SOCKET ClientSocketPipline(SOCKET _Socket)
{
/*Socket types are defined in sys/socket.h. These types--SOCK_STREAM,SOCK_DGRAM,or SOCK_RAW--are supported by AF_INET and AF_UNIX. The following creates a stream socket in the Internet domain:*/
if ((_Socket = socket(AF_INET,SOCK_STREAM,0)) < 0)
{
return _Socket = CloseSocket(_Socket);
}
struct timeval timeout;
memset(&timeout,sizeof(timeout));
timeout.tv_sec = 2;
timeout.tv_usec = 0;
if ( setsockopt (_Socket,SOL_SOCKET,SO_SNDTIMEO,(char *)&timeout,sizeof(timeout)) < 0 &&
setsockopt (_Socket,SO_RCVTIMEO,sizeof(timeout)) < 0 )
{
return _Socket = CloseSocket(_Socket);
}
return _Socket;
}
void ClientConnectionCall()
{
SOCKET ConnectSocket;
ConnectSocket = INVALID_SOCKET;
ConnectSocket = ClientSocketPipline(ConnectSocket);
SOCKADDR_IN SocketAddres;
memset(&SocketAddres,sizeof(SocketAddres));
/*Convert IPv4 and IPv6 addresses from text to binary form*/
if(inet_pton(AF_INET,"192.160.1.1",&SocketAddres.sin_addr.s_addr)>0)
{
SocketAddres.sin_port = htons(1000); // and 2000
SocketAddres.sin_family = AF_INET;
ConnectSocket = Connect(ConnectSocket,SocketAddres);
}
}
int _tmain(int argc,_TCHAR* argv[])
{
Initialize();
ClientConnectionCall();
return 0;
}
服务器代码监听器(端口号:1000):
SOCKET ServerClass::CloseSocket(SOCKET _Socket)
{
/*A shutdown() closes SOCK_STREAM sockets gracefully. Both processes can ackNowledge that they are no longer sending. OR disable sends and/or receives on a socket*/
shutdown(_Socket,SD_BOTH);
/*The closesocket function closes an existing socket.*/
closesocket(_Socket);
return _Socket = INVALID_SOCKET;
}
SOCKET ServerClass::Bind(SOCKET _Socket,SOCKADDR_IN _Address)
{
/*bind : Associate a local address with a socket.*/
if(::bind(_Socket,(struct sockaddr*)&_Address,sizeof(_Address)) == SOCKET_ERROR)
{
_Socket = CloseSocket(_Socket);
}
return _Socket;
}
SOCKET ServerClass::ServerSocketPipline(SOCKET _Socket,int _Type)
{
/*Socket types are defined in sys/socket.h. These types--SOCK_STREAM,or SOCK_RAW--are supported by AF_INET and AF_UNIX. The following creates a stream socket in the Internet domain:*/
if ((_Socket = socket(AF_INET,_Type,0)) < 0)
{
return _Socket = CloseSocket(_Socket);
}
int opt = 1;
/* Set socket keep connections alive */
if (setsockopt(_Socket,SO_REUSEADDR,(char *)&opt,sizeof(opt)) == SOCKET_ERROR)
{
return _Socket = CloseSocket(_Socket);
}
return _Socket;
}
SOCKET ServerClass::CreateSocket(SOCKET _Socket,int _Port)
{
_Socket = INVALID_SOCKET;
_Socket = ServerSocketPipline(_Socket,SOCK_STREAM);
SOCKADDR_IN SocketAddres;
memset(&SocketAddres,sizeof(SocketAddres));
SocketAddres.sin_addr.s_addr = htonl(INADDR_ANY);
SocketAddres.sin_port = htons(_Port);
SocketAddres.sin_family = AF_INET;
//Associate a local address with a socket.
_Socket = Bind( _Socket,SocketAddres );
/*Establish a socket to listen for incoming connection*/
if(::listen(_Socket,5) != SOCKET_ERROR)
{
//Socket listen success.
}
else
{
//Socket listen Failed.
_Socket = SOCKET_ERROR;
}
return _Socket;
}
DWORD WINAPI ServerClass::SocketListener(LPVOID threadParam)
{
if(threadParam != NULL)
{
ServerClass *thisClass = (ServerClass *)threadParam;
SOCKET tempSocket = INVALID_SOCKET;
socklen_t addrlen = sizeof(struct sockaddr_in);
SOCKADDR_IN SocketAddres;
memset(&SocketAddres,sizeof(SocketAddres));
SocketAddres.sin_addr.s_addr = htonl(INADDR_ANY);
SocketAddres.sin_port = htons(1000);
SocketAddres.sin_family = AF_INET;
if(thisClass->m_BindSock != INVALID_SOCKET)
{
/*Accept a connection on a socket.*/
tempSocket = ::accept( thisClass->m_BindSock,(struct sockaddr*)&SocketAddres,&addrlen);
if(tempSocket != INVALID_SOCKET)
{
SetEvent(thisClass->m_SocketThreadHandle);
}
else
{
tempSocket = thisClass->CloseSocket(tempSocket);
SetEvent(thisClass->m_SocketThreadHandle);
}
}
}
return 0;
}
ServerClass::ServerMainCall(void)
{
Initialize();
m_BindSock = CreateSocket(m_BindSock,1000);
m_SocketThreadHandle = CreateThread(NULL,SocketListener,this,NULL);
WaitForSingleObject(m_SocketThreadHandle,INFINITE);
int msgBoxID = MessageBox( NULL,L"Connection request received from first client",L"",MB_ICONEXCLAMATION | MB_OK );
}
服务器代码监听器(端口号:2000):
SOCKET ServerClass::CloseSocket(SOCKET _Socket)
{
/*A shutdown() closes SOCK_STREAM sockets gracefully. Both processes can ackNowledge that they are no longer sending. OR disable sends and/or receives on a socket*/
shutdown(_Socket,sizeof(opt)) == SOCKET_ERROR)
{
return _Socket = CloseSocket(_Socket);
}
return _Socket;
}
SOCKET ServerClass::CreateSocket(SOCKET _Socket,5) != SOCKET_ERROR)
{
//Socket listen success.
}
else
{
//Socket listen Failed.
_Socket = SOCKET_ERROR;
}
return _Socket;
}
DWORD WINAPI ServerClass::SocketListener(LPVOID threadParam)
{
if(threadParam != NULL)
{
ServerClass *thisClass = (ServerClass *)threadParam;
SOCKET tempSocket = INVALID_SOCKET;
socklen_t addrlen = sizeof(struct sockaddr_in);
SOCKADDR_IN SocketAddres;
memset(&SocketAddres,sizeof(SocketAddres));
SocketAddres.sin_addr.s_addr = htonl(INADDR_ANY);
SocketAddres.sin_port = htons(2000);
SocketAddres.sin_family = AF_INET;
if(thisClass->m_BindSock != INVALID_SOCKET)
{
/*Accept a connection on a socket.*/
tempSocket = ::accept( thisClass->m_BindSock,&addrlen);
if(tempSocket != INVALID_SOCKET)
{
SetEvent(thisClass->m_SocketThreadHandle);
}
else
{
tempSocket = thisClass->CloseSocket(tempSocket);
SetEvent(thisClass->m_SocketThreadHandle);
}
}
}
return 0;
}
ServerClass::ServerMainCall(void)
{
Initialize();
m_BindSock = CreateSocket(m_BindSock,2000);
m_SocketThreadHandle = CreateThread(NULL,NULL);
WaitForSingleObject(m_SocketThreadHandle,L"Connection request received from second client",MB_ICONEXCLAMATION | MB_OK);
}
解决方法
终于找到问题的答案了。问题是由于服务器机器端的防火墙阻止。禁用它后,一切开始工作,有关更多详细信息,请访问以下链接: