非阻塞模式无法连接服务器

colorsky_010 2008-10-08 03:02:43
设置为非阻塞模式后,直接运行程序不能连接数据库;但是单步调试的时候,程序会在第34行返回,也就是说能连接数据库,为什么会出现这样的情况呢?我若不设置非阻塞模式,是可以正常连接数据库的。

/**
* 创建非阻塞套接字
*/
1 BOOL InitSockt(void)
2 {
3 int reVal;//返回值
4 WSADATA wsData;
5 reVal = WSAStartup(MAKEWORD(2,2),&wsData);//初始化Windows Sockets Dll

//创建套接字
6 sClient = socket(AF_INET, SOCK_STREAM, 0);
7 if(INVALID_SOCKET == sClient)
8 return FALSE;
//设置套接字非阻塞模式
9 unsigned long ul = 1;
10 reVal = ioctlsocket(sClient, FIONBIO, (unsigned long*)&ul);

11 if (reVal == SOCKET_ERROR)
12 return FALSE;
13 return TRUE;
14}

/**
* 连接服务器
*/
15 BOOL ConnectServer(void)
16 {
17 int reVal;//返回值
18 sockaddr_in serAddr;//服务器地址
19 serAddr.sin_family = AF_INET;
20 serAddr.sin_port = htons(5555);
21 serAddr.sin_addr.S_un.S_addr = inet_addr("192.168.1.131");
22 for (;;)
23 {
//连接服务器
24 reVal = connect(sClient, (struct sockaddr*)&serAddr, sizeof(serAddr));

//处理连接错误
25 if(SOCKET_ERROR == reVal)
26 {
27 int nErrCode = WSAGetLastError();
28 if( WSAEWOULDBLOCK == nErrCode ||//连接还没有完成
29 WSAEINVAL == nErrCode)
30 {
31 continue;
32 }else if (WSAEISCONN == nErrCode)//连接已经完成
33 {
34 break;
35 }else//其它原因,连接失败
36 {
37 return FALSE;
38 }
39 }

40 if ( reVal == 0 )//连接成功
41 break;
42 }
43 bConnecting = TRUE;//服务器的连接状态
44 return TRUE;
45}
...全文
135 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
zkhraul 2008-12-08
  • 打赏
  • 举报
回复
想问下您个问题,为什么我采用非阻塞方式,在connect后调有select获得写属性要等两三分钟才返回可写呢
WinEggDrop 2008-10-08
  • 打赏
  • 举报
回复
非阻塞连接,象你上面的代码,调用connect()后,要在一个死循环内调用select()看是否有写的信号返回,如果有写信号返回,证实连接上了.如果一直到超时都没有信号返回,证明连接失败.
Win32Coder 2008-10-08
  • 打赏
  • 举报
回复
既然是非阻塞了,返回SOCKET_ERROR后(正在连接中),为何还要来个continue,继续connect呢。

等待返回结果就可以了。非阻塞socket,用select模式可以控制connect的超时。


SOCKET s = socket(AF_INET, SOCK_STREAM, 0);
if (INVALID_SOCKET == s)
{
printf("create a socket error!\n");
WSACleanup();
return -1;
}

// 设置为非阻塞
int nRet = 0;
u_long lRet = 1;
nRet = ioctlsocket(s, FIONBIO, &lRet);
if (SOCKET_ERROR == nRet)
{
printf("set socket error!\n");
closesocket(s);
WSACleanup();
return -1;
}

sockaddr_in servAddr;
ZeroMemory(&servAddr, sizeof(servAddr));
servAddr.sin_addr.S_un.S_addr = inet_addr("192.168.1.131");
servAddr.sin_family = AF_INET;
servAddr.sin_port = htons(5555);

// 非阻塞连接
int sAccept = connect(s, (sockaddr*)&servAddr, sizeof(servAddr));
if (SOCKET_ERROR == sAccept)
{
DWORD dwLastErr = WSAGetLastError();
if (WSAEWOULDBLOCK == dwLastErr)
{
printf("connecting......\n");
}
}

// 设置连接超时为5秒
fd_set fdWrite;
FD_ZERO(&fdWrite);
FD_SET(s, &fdWrite);
timeval time;
time.tv_sec = 5;
time.tv_usec = 0;
nRet = select(0, NULL, &fdWrite, NULL, &time);
if (SOCKET_ERROR == nRet)
{
printf("select socket error!\n");
closesocket(s);
WSACleanup();
return -1;
}

// 检查是否连接成功
if (!FD_ISSET(s, &fdWrite))
{
printf("connect error!\n");
closesocket(s);
WSACleanup();
return -1;
}
printf("connect ok!\n");

// 设置为阻塞
lRet = 0;
nRet = ioctlsocket(s, FIONBIO, &lRet);
if (SOCKET_ERROR == nRet)
{
printf("set socket error!\n");
closesocket(s);
WSACleanup();
return -1;
}

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧