WSAEVENTSELECT模型中connect返回WSAEWOULDBLOCK错误怎么解决?
如题所述,我在程序中采用了WASEventSelect模型,该模型会把套接字自动设置为非阻塞模式。
然后我给监听套接字关联了FD_ACCEPT、FD_CLOSE事件。给客户端连接服务器的套接字关联了FD_READ、FD_WRITE、FD_CLOSE事件,但是不知道为什么在调用API函数connect()时,总是返回WSAEWOULDBLOCK错误!
查过了MSDN,说是非阻塞模式的原因,但是我在网上找到的一个例子,为什么他的可以啊?求教高手帮忙解答!
谢谢!
下面附上的代码:
服务器端:
- C/C++ code
PST_LISTEN_OBJ CTCPCommunicatio::SetListenObj(BYTE abyServerIP[IP_BYTE_LENGTH],UINT uiServerPort){ USES_CONVERSION; //新建一个监听套接字对象 PST_LISTEN_OBJ pstListenObj=new ST_LISTEN_OBJ; //初始化访问线程对象关键段,每个监听套接字在接收到客户连接后将新建的套 //接字对象加入空闲线程对象中,此时需要访问线程对象链表。在本库中,每个 //监听套接字对应一个线程对象链表,以表明该线程对象链表中的套接字均是由 //同一个监听套接字接受连接产生的。 InitializeCriticalSection(&(pstListenObj->crt_ThreadObj)); //创建监听套接字 pstListenObj->sktListen=socket(AF_INET, // 协议地址家族,windows下一般为AF_INET SOCK_STREAM, // 协议套接字类型,此处TCP采用流式套接字 IPPROTO_TCP); // 协议,此处采用TCP协议 //判断监听套接字是否创建成功 if (INVALID_SOCKET==(pstListenObj->sktListen)) { //错误码 int iSocketErr=WSAGetLastError(); if (iSocketErr==WSANOTINITIALISED) { CCsccLog::DebugPrint("请正确加载套接字版本库!\n"); } //创建套接字失败,返回不可用的套接字 return NULL; } // 服务器IP地址 CString strServerIp=_T(""); strServerIp.Format(_T("%d.%d.%d.%d"),abyServerIP[0],abyServerIP[1],abyServerIP[2],abyServerIP[3]); char* pcServerIP=""; pcServerIP=W2A(strServerIp); //绑定服务器IP地址 sockaddr_in sdServerAddr;//服务器端地址簇 sdServerAddr.sin_family=AF_INET;// 协议地址家族,windows下一般为AF_INET sdServerAddr.sin_addr.S_un.S_addr=inet_addr(pcServerIP);//服务器IP sdServerAddr.sin_port=htons(uiServerPort); //端口号,主机字节序三转换为网络字节序 //绑定套接字 int iBindErr=bind(pstListenObj->sktListen,(LPSOCKADDR)&sdServerAddr,sizeof(sdServerAddr)); if (iBindErr==SOCKET_ERROR) { CCsccLog::DebugPrint("设置监听套接字出错!\n"); return FALSE; } //初始线程对象个数 pstListenObj->uiCurrentThdNum=0; //服务器监听地址及端口 memcpy(pstListenObj->abyServerIp,abyServerIP,IP_BYTE_LENGTH); pstListenObj->uiServerPort=uiServerPort; //创建监听套接字关联的事件 pstListenObj->hListenEvent=WSACreateEvent(); WSAEventSelect(pstListenObj->sktListen,pstListenObj->hListenEvent,FD_ACCEPT|FD_WRITE|FD_CLOSE); pstListenObj->lpClsObj=this; //服务器退出事件,自动复位,默认无信号 pstListenObj->hServerExit=CreateEvent(NULL,FALSE,FALSE,NULL); //启动监听服务 int iErrListen=listen(pstListenObj->sktListen,SOMAXCONN); if (iErrListen==SOCKET_ERROR) { CCsccLog::DebugPrint("监听失败!\n"); } //启动监听套接字网络事件处理线程 pstListenObj->pclsThdListen=AfxBeginThread(Thread_Listen_Proc,(LPVOID)(pstListenObj)); //HACK:此处是否需要传递线程参数待定 EnterCriticalSection(&(m_Crt_ListenObj)); //将监听套接字对象加入链表 m_lstListenObj.AddHead(pstListenObj); //UNDONE:为判断是否重复 LeaveCriticalSection(&m_Crt_ListenObj); return pstListenObj;}客户端:
- C/C++ code
SOCKET CTCPCommunicatio::AddClientObj(BYTE abyServerIp[IP_BYTE_LENGTH],UINT uiServerPort,BYTE abyClientIp[IP_BYTE_LENGTH],UINT uiClientPort){ USES_CONVERSION; // 服务器端IP CString strServerIp=_T(""); strServerIp.Format(_T("%d.%d.%d.%d"),abyServerIp[0],abyServerIp[1],abyServerIp[2],abyServerIp[3]); char* pcServerIp=""; pcServerIp=W2A(strServerIp); // 客户端IP CString strClientIp=_T(""); strClientIp.Format(_T("%d.%d.%d.%d"),abyClientIp[0],abyClientIp[1],abyClientIp[2],abyClientIp[3]); char* pcClientIp=""; pcClientIp=W2A(strClientIp); //创建TCP通信套接字 SOCKET sktConnectServer=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); if (INVALID_SOCKET==sktConnectServer) { CCsccLog::DebugPrint("创建连接服务器通信套接字错误!\n"); return FALSE; } int ireVal=0; SOCKADDR_IN sdServerAddr;//服务器端地址簇 sdServerAddr.sin_family=AF_INET; sdServerAddr.sin_addr.S_un.S_addr=inet_addr(pcServerIp);//发送本机IP sdServerAddr.sin_port=htons(uiServerPort); //端口号,主机字节序三转换为网络字节序 int iServerLength=sizeof(SOCKADDR_IN); SOCKADDR_IN sdClientAddr; sdClientAddr.sin_family=AF_INET; sdClientAddr.sin_addr.S_un.S_addr=inet_addr(pcClientIp); sdServerAddr.sin_port=htons(uiClientPort); PST_SERVER_OBJ pstServerObj=SetClientObj(sktConnectServer,sdClientAddr); //将TCP通信套接字加入到客户端对象中 ireVal=connect(sktConnectServer,(SOCKADDR*)&sdServerAddr,iServerLength); if (SOCKET_ERROR == ireVal) { int iErrCode=WSAGetLastError(); if (iErrCode==WSAEWOULDBLOCK) { CCsccLog::DebugPrint("客户端连接服务器出错!\n"); return FALSE; } } return sktConnectServer;}
[解决办法]
恭喜,捡分。
[解决办法]