18,356
社区成员
发帖
与我相关
我的任务
分享
//服务器连接测试函数
BOOL CMainFrame::ServerConnectTest(char* pszIP, short nPort)
{
SOCKADDR_IN LocalAddr = {0};//本地地址
SOCKADDR_IN SerAddr = {0};//服务器地址
int nLen = sizeof(SerAddr);
BOOL bRet = FALSE;
DWORD dwWait = 0;
//服务器连接测试, 发送2个CMD_CONNECT_TEST
CommunicationCMD cmd = {0};
cmd.nCmd1 = CMD_CONNECT_TEST;
cmd.nCmd2 = CMD_CONNECT_TEST;
DWORD dwSendByte = 0;
OVERLAPPED ol = {0};
DWORD dwFlags = 0;
char szRecvbuf[8] = {0};
WSABUF wsabuf = {0};//接收缓冲区
DWORD dwRecv = 0;//接收长度
SOCKET s = ::WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED);
if (INVALID_SOCKET == s)
goto OPFAILED;
LocalAddr.sin_family = AF_INET;
LocalAddr.sin_port = ::htons(105);//使用0让系统自动分配
LocalAddr.sin_addr.s_addr = INADDR_ANY;
SerAddr.sin_family = AF_INET;
SerAddr.sin_port = ::htons(nPort);
SerAddr.sin_addr.s_addr = ::inet_addr(pszIP);
if (::bind(s, (sockaddr*)&LocalAddr, nLen) == SOCKET_ERROR)
goto OPFAILED;
//连接服务器并发送数据
bRet = m_pfnConnectEx(s, (sockaddr*)&SerAddr, nLen, (char*)&cmd, sizeof(cmd), &dwSendByte, &ol);
if (bRet == FALSE)
{
if (::WSAGetLastError() != ERROR_IO_PENDING)
goto OPFAILED;
}
DWORD dwTime = ::GetTickCount();
while(::GetTickCount() - dwTime <= 3000)//等待3秒
{
bRet = ::WSAGetOverlappedResult(s, &ol, &dwSendByte, FALSE, &dwFlags);
if (bRet)
break;
::Sleep(1);
}
//发送的字节数,小于缓冲区长度,失败
if (dwSendByte < sizeof(cmd))
goto OPFAILED;
::ResetEvent(ol.hEvent);
wsabuf.buf = szRecvbuf;
wsabuf.len = sizeof(szRecvbuf);
//发送完就接收
bRet = ::WSARecv(s, &wsabuf, 1, &dwRecv, &dwFlags, &ol, NULL);
if (SOCKET_ERROR == bRet && ::WSAGetLastError() != ERROR_IO_PENDING)
goto OPFAILED;
dwSendByte = 0;
dwTime = ::GetTickCount();
while(::GetTickCount() - dwTime <= 3000)//等待3秒
{
bRet = ::WSAGetOverlappedResult(s, &ol, &dwSendByte, FALSE, &dwFlags);
if (bRet)
break;
::Sleep(1);
}
if (dwSendByte != 8)
goto OPFAILED;
CommunicationCMD* pCmd = (CommunicationCMD*)szRecvbuf;
////数据接收完毕, 判断是否正常
if (pCmd->nCmd1 != CMD_CONNECT_TEST &&
pCmd->nCmd2 != CMD_CONNECT_TEST)
goto OPFAILED;
pCmd->nCmd1 = CMD_CONNECT_CLOSE;
pCmd->nCmd2 = CMD_CONNECT_CLOSE;
dwSendByte = 0;
//发送关闭连接命令
bRet = ::WSASend(s, &wsabuf, 1, &dwSendByte, 0, &ol, NULL);
if (SOCKET_ERROR == bRet && ::WSAGetLastError() != ERROR_IO_PENDING)
goto OPFAILED;
dwTime = ::GetTickCount();
while(::GetTickCount() - dwTime <= 3000)//等待3秒
{
bRet = ::WSAGetOverlappedResult(s, &ol, &dwSendByte, FALSE, &dwFlags);
if (bRet)
break;
::Sleep(1);
}
if (dwSendByte != 8)
goto OPFAILED;
::CloseHandle(ol.hEvent);
::closesocket(s);
return TRUE;
OPFAILED:
if (s != INVALID_SOCKET)
::closesocket(s);
return FALSE;
}
随便写了一个函数, 经测试是可以再次绑定到同一个IP和端口的