JUST DO IT ~

我只想当个程序员

遇到一个tcp socket问题。

 

 

  SetBlockMode(false);  // NONBLOCK mode      
 e = connect(m_socket, (struct sockaddr*)&addr, sizeof (addr));  
 if (e<0)       {      
 e = GET_LAST_SOCK_ERROR();  printf(" socket error code = %d \n",e);       
 if ((e==EWOULDBLOCK||e==EINPROGRESS || e == WSAEWOULDBLOCK ) && CheckSendAvailable(waitms)>0)    
 {             e = 0; // 表示连接成功      
  }  
else   {  
           e = -1; // 表示连接失败,或者在等待的时间之内连接失败          }
 
我临时修改。
         if ((e==EWOULDBLOCK||e==EINPROGRESS || e == WSAEWOULDBLOCK ) && CheckSendAvailable(waitms)>0)
 
WSAEWOULDBLOCK  = 10037 
 
 
 
问题找到了。
切换到项目配置。平台工具集---->vs2008   连接win sdk 6的库
切换到项目配置。平台工具集---->vs2012 连接win  sdk  8 的库
有区别。
 
 

E6~A%]$`JD$GI9K]TY[MO~Q

 

正在生成代码...
1>  Microsoft (R) Windows (R) Resource Compiler Version 6.0.5724.0
1> 
1>  Copyright (C) Microsoft Corporation.  All rights reserved.
1> 
1> 
1> 
1>  正在搜索库
1>      正在搜索 C:\Program Files\\Microsoft SDKs\Windows\v6.0A\lib\ws2_32.lib:
1>      正在搜索 C:\Program Files\\Microsoft SDKs\Windows\v6.0A\lib\odbc32.lib:
1>      正在搜索 C:\Program Files\\Microsoft SDKs\Windows\v6.0A\lib\odbccp32.lib:
1>      正在搜索 C:\Program Files\\Microsoft SDKs\Windows\v6.0A\lib\kernel32.lib:
1>      正在搜索 C:\Program Files\\Microsoft SDKs\Windows\v6.0A\lib\user32.lib:
1>      正在搜索 C:\Program Files\\Microsoft SDKs\Windows\v6.0A\lib\gdi32.lib:
1>      正在搜索 C:\Program Files\\Microsoft SDKs\Windows\v6.0A\lib\winspool.lib:
1>      正在搜索 C:\Program Files\\Microsoft SDKs\Windows\v6.0A\lib\comdlg32.lib:
1>      正在搜索 C:\Program Files\\Microsoft SDKs\Windows\v6.0A\lib\advapi32.lib:
1>      正在搜索 C:\Program Files\\Microsoft SDKs\Windows\v6.0A\lib\shell32.lib:
1>      正在搜索 C:\Program Files\\Microsoft SDKs\Windows\v6.0A\lib\ole32.lib:
1>      正在搜索 C:\Program Files\\Microsoft SDKs\Windows\v6.0A\lib\oleaut32.lib:
1>      正在搜索 C:\Program Files\\Microsoft SDKs\Windows\v6.0A\lib\uuid.lib:
1>      正在搜索 c:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\lib\LIBCMTD.lib:
1>      正在搜索 c:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\lib\OLDNAMES.lib:
1>      正在搜索 c:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\lib\libcpmtd.lib:
1>      正在搜索 C:\Program Files\\Microsoft SDKs\Windows\v6.0A\lib\ws2_32.lib:
1>      正在搜索 C:\Program Files\\Microsoft SDKs\Windows\v6.0A\lib\odbc32.lib:
1>      正在搜索 C:\Program Files\\Microsoft SDKs\Windows\v6.0A\lib\odbccp32.lib:
1>      正在搜索 C:\Program Files\\Microsoft SDKs\Windows\v6.0A\lib\kernel32.lib:
1>      正在搜索 C:\Program Files\\Microsoft SDKs\Windows\v6.0A\lib\user32.lib:
1>      正在搜索 C:\Program Files\\Microsoft SDKs\Windows\v6.0A\lib\gdi32.lib:
1>      正在搜索 C:\Program Files\\Microsoft SDKs\Windows\v6.0A\lib\winspool.lib:
1>      正在搜索 C:\Program Files\\Microsoft SDKs\Windows\v6.0A\lib\comdlg32.lib:
1>      正在搜索 C:\Program Files\\Microsoft SDKs\Windows\v6.0A\lib\advapi32.lib:
1>      正在搜索 C:\Program Files\\Microsoft SDKs\Windows\v6.0A\lib\shell32.lib:
1>      正在搜索 C:\Program Files\\Microsoft SDKs\Windows\v6.0A\lib\ole32.lib:
1>      正在搜索 C:\Program Files\\Microsoft SDKs\Windows\v6.0A\lib\oleaut32.lib:
1>      正在搜索 C:\Program Files\\Microsoft SDKs\Windows\v6.0A\lib\uuid.lib:
1>      正在搜索 c:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\lib\LIBCMTD.lib:
1>      正在搜索 c:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\lib\OLDNAMES.lib:
1>      正在搜索 c:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\lib\libcpmtd.lib:
1>      正在搜索 C:\Program Files\\Microsoft SDKs\Windows\v6.0A\lib\ws2_32.lib:
1>      正在搜索 C:\Program Files\\Microsoft SDKs\Windows\v6.0A\lib\odbc32.lib:
1>      正在搜索 C:\Program Files\\Microsoft SDKs\Windows\v6.0A\lib\odbccp32.lib:
1>      正在搜索 C:\Program Files\\Microsoft SDKs\Windows\v6.0A\lib\kernel32.lib:
1>      正在搜索 C:\Program Files\\Microsoft SDKs\Windows\v6.0A\lib\user32.lib:
1>      正在搜索 C:\Program Files\\Microsoft SDKs\Windows\v6.0A\lib\gdi32.lib:
1>      正在搜索 C:\Program Files\\Microsoft SDKs\Windows\v6.0A\lib\winspool.lib:
1>      正在搜索 C:\Program Files\\Microsoft SDKs\Windows\v6.0A\lib\comdlg32.lib:
1>      正在搜索 C:\Program Files\\Microsoft SDKs\Windows\v6.0A\lib\advapi32.lib:
1>      正在搜索 C:\Program Files\\Microsoft SDKs\Windows\v6.0A\lib\shell32.lib:
1>      正在搜索 C:\Program Files\\Microsoft SDKs\Windows\v6.0A\lib\ole32.lib:
1>      正在搜索 C:\Program Files\\Microsoft SDKs\Windows\v6.0A\lib\oleaut32.lib:
1>      正在搜索 C:\Program Files\\Microsoft SDKs\Windows\v6.0A\lib\uuid.lib:
1> 
1>  已完成库搜索
1>  Microsoft (R) Windows (R) Resource Compiler Version 6.0.5724.0
1> 
1>  Copyright (C) Microsoft Corporation.  All rights reserved.
1> 
1> 
1>  MDUSJS.vcxproj -> D:\dev\cmd3\cmdsiimdsi\MDUSJS2012\.\Debug\MDUSJS.exe
========== 生成: 成功 1 个,失败 0 个,最新 0 个,跳过 0 个 ==========

 

平台工具 连接的库不一样。

 

Q__${K)0%R54TA9X8E8EUQJ

 


>  正在生成代码...
1>dbf.obj : warning LNK4075: 忽略“/EDITANDCONTINUE”(由于“/SAFESEH”规范)
1> 
1>  正在搜索库
1>      正在搜索 C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\ws2_32.lib:
1>      正在搜索 C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\odbc32.lib:
1>      正在搜索 C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\odbccp32.lib:
1>      正在搜索 C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\kernel32.lib:
1>      正在搜索 C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\user32.lib:
1>      正在搜索 C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\gdi32.lib:
1>      正在搜索 C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\winspool.lib:
1>      正在搜索 C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\comdlg32.lib:
1>      正在搜索 C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\advapi32.lib:
1>      正在搜索 C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\shell32.lib:
1>      正在搜索 C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\ole32.lib:
1>      正在搜索 C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\oleaut32.lib:
1>      正在搜索 C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\uuid.lib:
1>      正在搜索 D:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\lib\LIBCMTD.lib:
1>      正在搜索 D:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\lib\OLDNAMES.lib:
1>      正在搜索 D:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\lib\libcpmtd.lib:
1>      正在搜索 C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\ws2_32.lib:
1>      正在搜索 C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\odbc32.lib:
1>      正在搜索 C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\odbccp32.lib:
1>      正在搜索 C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\kernel32.lib:
1>      正在搜索 C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\user32.lib:
1>      正在搜索 C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\gdi32.lib:
1>      正在搜索 C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\winspool.lib:
1>      正在搜索 C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\comdlg32.lib:
1>      正在搜索 C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\advapi32.lib:
1>      正在搜索 C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\shell32.lib:
1>      正在搜索 C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\ole32.lib:
1>      正在搜索 C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\oleaut32.lib:
1>      正在搜索 C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\uuid.lib:
1>      正在搜索 D:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\lib\LIBCMTD.lib:
1>      正在搜索 D:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\lib\OLDNAMES.lib:
1>      正在搜索 D:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\lib\libcpmtd.lib:
1>      正在搜索 C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\ws2_32.lib:
1>      正在搜索 C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\odbc32.lib:
1>      正在搜索 C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\odbccp32.lib:
1>      正在搜索 C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\kernel32.lib:
1>      正在搜索 C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\user32.lib:
1>      正在搜索 C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\gdi32.lib:
1>      正在搜索 C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\winspool.lib:
1>      正在搜索 C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\comdlg32.lib:
1>      正在搜索 C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\advapi32.lib:
1>      正在搜索 C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\shell32.lib:
1>      正在搜索 C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\ole32.lib:
1>      正在搜索 C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\oleaut32.lib:
1>      正在搜索 C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\uuid.lib:
1> 
1>  已完成库搜索
1> 
1>  正在搜索库
1>      正在搜索 C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\ws2_32.lib:
1>      正在搜索 C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\odbc32.lib:
1>      正在搜索 C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\odbccp32.lib:
1>      正在搜索 C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\kernel32.lib:
1>      正在搜索 C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\user32.lib:
1>      正在搜索 C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\gdi32.lib:
1>      正在搜索 C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\winspool.lib:
1>      正在搜索 C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\comdlg32.lib:
1>      正在搜索 C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\advapi32.lib:
1>      正在搜索 C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\shell32.lib:
1>      正在搜索 C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\ole32.lib:
1>      正在搜索 C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\oleaut32.lib:
1>      正在搜索 C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\uuid.lib:
1>      正在搜索 D:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\lib\LIBCMTD.lib:
1>      正在搜索 D:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\lib\OLDNAMES.lib:
1>      正在搜索 D:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\lib\libcpmtd.lib:
1>      正在搜索 C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\ws2_32.lib:
1>      正在搜索 C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\odbc32.lib:
1>      正在搜索 C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\odbccp32.lib:
1>      正在搜索 C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\kernel32.lib:
1>      正在搜索 C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\user32.lib:
1>      正在搜索 C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\gdi32.lib:
1>      正在搜索 C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\winspool.lib:
1>      正在搜索 C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\comdlg32.lib:
1>      正在搜索 C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\advapi32.lib:
1>      正在搜索 C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\shell32.lib:
1>      正在搜索 C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\ole32.lib:
1>      正在搜索 C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\oleaut32.lib:
1>      正在搜索 C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\uuid.lib:
1> 
1>  已完成库搜索
1>  MDUSJS.vcxproj -> D:\dev\cmd3\cmdsiimdsi\MDUSJS2012\.\Debug\MDUSJS.exe
========== 生成: 成功 1 个,失败 0 个,最新 0 个,跳过 0 个 ==========

 

 

 

 

 

 

 
 
 

参考:

ms connect

http://msdn.microsoft.com/en-us/library/windows/desktop/ms737625(v=vs.85).aspx

 

ioctlsocket function 控制柱塞非柱塞

http://msdn.microsoft.com/en-us/library/windows/desktop/ms738573(v=vs.85).aspx

 

TCP/IP编程基础——超时、多路复用、非阻塞

 

 

http://blog.csdn.net/s3olo/article/details/8014872

 

 

 

http://developerweb.net/viewtopic.php?id=7246

 

 

代码 windows  tcp 通过select方式实现 connect non block

http://bbs.csdn.net/topics/10426810

 

 

 

http://msdn.microsoft.com/en-us/library/windows/desktop/ms740668(v=vs.85).aspx

Windows Sockets Error Codes

 

***************

测试模拟工具发送大数据量消息时,发现时而发送成功,时而失败。追踪代码发现,抛出的是一个错误码为10035的socket错误。上网查资料发现这个错误码描述是Service temporarily unavailable.也就是说有可能send的时候遇到socket缓冲区满,无法写入,引起发送失败。

  如果是这样的话,那么这就是一个常规的异常情况,需要对它进行处理,而不是异常退出。

  最后代码改成这个样子,send然后分析返回结果,如果错误,且错误码为10035,那么就重发,直到发成功时,break。

  目前尚不知道,这样改的副作用有没有,反正现在问题暂时解决鸟

***********************************

 

Winsock connect函数返回错误,使用WSAGetLastError得到10035,10037,是什么原因
MSDN注释:
WSAEWOULDBLOCK
10035
Resource temporarily unavailable.
This error is returned from operations on nonblocking sockets that cannot be completed immediately, for example recv when no data is queued to be read from the socket. It is a nonfatal error, and the operation should be retried later. It is normal for WSAEWOULDBLOCK to be reported as the result from calling connect on a nonblocking SOCK_STREAM socket, since some time must elapse for the connection to be established.
WSAEALREADY
10037
Operation already in progress.
An operation was attempted on a nonblocking socket with an operation already in progress—that is, calling connect a second time on a nonblocking socket that is already connecting, or canceling an asynchronous request (WSAAsyncGetXbyY) that has already been canceled or completed.
网络翻译:
10035—WSAEWOULDBLOCK
资源暂时不可用。对非锁定套接字来说,如果请求操作不能立即执行的话,通常会返回这个错误。比如说,在一个非暂停套接字上调用 connect,就会返回这个错误。因为连接请求不能立即执行。
10037—WSAEALREADY
操作已完成。一般来说,在非锁定套接字上尝试已处于进程中的操作时,会产生这个错误。比如,在一个已处于连接进程的非锁定套接字上,再一次调用 connect 或 WSAConnect。另外,服务提供者处于执行回调函数(针对支持回调例程的 Winsock函数)的进程中时,也会出现这个错误。
我描述下问题:使用socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);创建一个TCP/IP套接字,然后创建一个线程,不停地用connect函数进行链接,直到链接成功,才退出线程,问题来了,connect函数它有时候返回成功,有时候又返回错误,用WSAGetLastError得到享受10035, 10037这两种错误值,我将错误值打印出来,结果是:10035,10035,10037,10037,10037,10037,10037.......,10037。

****************************************************************

 

 

 

 

WSADATA wsd;
SOCKET cClient;
int ret;
struct sockaddr_in server;
hostent *host=NULL;
if(WSAStartup(MAKEWORD(2,0),&wsd)){return 0;}
cClient=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(cClient==INVALID_SOCKET){return 0;}
//set Recv and Send time out
int TimeOut=6000; //设置发送超时6秒
if(::setsockopt(cClient,SOL_SOCKET,SO_SNDTIMEO,(char *)&TimeOut,sizeof(TimeOut))==SOCKET_ERROR){
return 0;
}
TimeOut=6000;//设置接收超时6秒
if(::setsockopt(cClient,SOL_SOCKET,SO_RCVTIMEO,(char *)&TimeOut,sizeof(TimeOut))==SOCKET_ERROR){
return 0;
}
//设置非阻塞方式连接
unsigned long ul = 1;
ret = ioctlsocket(cClient, FIONBIO, (unsigned long*)&ul);
if(ret==SOCKET_ERROR)return 0;
//连接
server.sin_family = AF_INET;
server.sin_port = htons(25);
server.sin_addr .s_addr = inet_addr((LPCSTR)pSmtp);
if(server.sin_addr.s_addr == INADDR_NONE){return 0;}
connect(cClient,(const struct sockaddr *)&server,sizeof(server));
//select 模型,即设置超时
struct timeval timeout ;
fd_set r;
FD_ZERO(&r);
FD_SET(cClient, &r);
timeout.tv_sec = 15; //连接超时15秒
timeout.tv_usec =0;
ret = select(0, 0, &r, 0, &timeout);
if ( ret <= 0 )
{
::closesocket(cClient);
return 0;
}
//一般非锁定模式套接比较难控制,可以根据实际情况考虑 再设回阻塞模式
unsigned long ul1= 0 ;
ret = ioctlsocket(cClient, FIONBIO, (unsigned long*)&ul1);
if(ret==SOCKET_ERROR){
::closesocket (cClient);
return 0;
}

 

 

 

//设置非阻塞方式连接
unsigned long ul = 1;
ret = ioctlsocket(cClient, FIONBIO, (unsigned long*)&ul);
if(ret==SOCKET_ERROR)return 0;
//连接
server.sin_family = AF_INET;
server.sin_port = htons(25);
server.sin_addr .s_addr = inet_addr((LPCSTR)pSmtp);
if(server.sin_addr.s_addr == INADDR_NONE){return 0;}
connect(cClient,(const struct sockaddr *)&server,sizeof(server));
//select 模型,即设置超时
struct timeval timeout ;
fd_set r;
FD_ZERO(&r);
FD_SET(cClient, &r);
timeout.tv_sec = 15; //连接超时15秒
timeout.tv_usec =0;
ret = select(0, 0, &r, 0, &timeout);
if ( ret <= 0 )
{
::closesocket(cClient);
return 0;
}
//一般非锁定模式套接比较难控制,可以根据实际情况考虑 再设回阻塞模式
unsigned long ul1= 0 ;
ret = ioctlsocket(cClient, FIONBIO, (unsigned long*)&ul1);
if(ret==SOCKET_ERROR){
::closesocket (cClient);
return 0;
}

 

------------------------------------------

 

 

// Socket中如何设置连接超时
// AntGhazi/2001.12.14 主页:antghazi.yeah.net
/*
把CSDN与中文yahoo翻了底朝天, 也没找到如何设置socket的连接超时的满意方法, 问此问题的兄弟已有一大堆,
这里偶就讲一下win下如何设置socket的connect超时. 设置connect的超时很简单, CSDN上也有人提到过使用select,
但却没有一个令人满意与完整的答案. 偶所讲的也正是select函数, 此函数集成在winsock1.1中, 简单点讲,"作用使
那些想避免在套接字调用过程中被锁定的应用程序, 采取一种有序的方式, 同时对多个套接字进行管理"
(<<Windows网络编程技术>>原话). 使用方法与解释请见《Windows网络编程技术》.
在使用此函数前, 需先将socket设置为非锁定模式, 这样, 在connect时,才会立马跳过,
同时, 通常也会产生一个WSAEWOULDBLOCK错误,这个错误没关系. 再执行select则是真正的超时.
*/
WSADATA wsd;
SOCKET cClient;
int ret;
struct sockaddr_in server;
hostent *host=NULL;
if(WSAStartup(MAKEWORD(2,0),&wsd))
{
return 0;
}
cClient=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(cClient==INVALID_SOCKET)
{
return 0;
}
//set Recv and Send time out
int TimeOut=6000; //设置发送超时6秒
if(::setsockopt(cClient,SOL_SOCKET,SO_SNDTIMEO,(char *)&TimeOut,sizeof(TimeOut))==SOCKET_ERROR)
{
return 0;
}
TimeOut=6000;//设置接收超时6秒
if(::setsockopt(cClient,SOL_SOCKET,SO_RCVTIMEO,(char *)&TimeOut,sizeof(TimeOut))==SOCKET_ERROR)
{
return 0;
}
//设置非阻塞方式连接
unsigned long ul = 1;
ret = ioctlsocket(cClient, FIONBIO, (unsigned long*)&ul);
if(ret==SOCKET_ERROR)return 0;
//连接
server.sin_family = AF_INET;
server.sin_port = htons(25);
server.sin_addr.s_addr = inet_addr((LPCSTR)pSmtp);
if(server.sin_addr.s_addr == INADDR_NONE)
{
return 0;
}
connect(cClient,(const struct sockaddr *)&server,sizeof(server));
//select 模型,即设置超时
struct timeval timeout ;
fd_set r;
FD_ZERO(&r);
FD_SET(cClient, &r);
timeout.tv_sec = 15; //连接超时15秒
timeout.tv_usec = 0;
ret = select(0, 0, &r, 0, &timeout);
if ( ret <= 0 )
{
::closesocket(cClient);
return 0;
}
//一般非锁定模式套接比较难控制,可以根据实际情况考虑 再设回阻塞模式
unsigned long ul1= 0 ;
ret = ioctlsocket(cClient, FIONBIO, (unsigned long*)&ul1);
if(ret==SOCKET_ERROR)
{
::closesocket (cClient);
return 0;
}
/////////////////////////////////////////////////////////////////
以前我从csdn上找到的,注意如果调用connect返回SOCKET_ERROR,那么你要调用 WSAGetLastError(),看错误是不是WSAEWOULDBLOCK,如果是,则忽略,否则是真的出错了。

 

 

 

-------------------------------------------------------------

 

 

这个应该是可以用的,因为我用过,我的代码是这样的,供你参考
LPHOSTENT ScanIPAddr(DWORD dwIP)
{
SOCKET sock = INVALID_SOCKET;
LPHOSTENT lphost = NULL;
SOCKADDR_IN server;
u_long ul = 1;
struct timeval timeout ;
fd_set r;
memset(&server, 0, sizeof(server));
server.sin_family = AF_INET;
server.sin_port = _nPort;
server.sin_addr.s_addr = htonl((u_long)dwIP);
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(sock == INVALID_SOCKET)
return NULL;
//设置非阻塞方式连接
if(ioctlsocket(sock, FIONBIO, (u_long*)&ul)==SOCKET_ERROR)
return NULL;
if(0 != connect(sock, (SOCKADDR*)&server, sizeof(server)))
{
if(WSAGetLastError() != WSAEWOULDBLOCK)
{
closesocket(sock);
return NULL;
}
}
//select 模型,即设置超时
FD_ZERO(&r);
FD_SET(sock, &r);
timeout.tv_sec = 0; //连接超时0秒
timeout.tv_usec = 700;
if(select(0, 0, &r, 0, &timeout) <= 0)
{
closesocket(sock);
return NULL;
}
lphost = gethostbyaddr((const char *)&(server.sin_addr), 4, AF_INET);
closesocket(sock);
return lphost;
}

 

 

 

-----------------------------------------------------------------------------

 

 

 

下面是我的实现代码:
char sBuf[2048];
    int i;
int iSRTimeOut = 6000;
    u_long arg=1;
    rc4_key key;
    int r;
    struct sockaddr_in sockaddr; 
    sock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    if (sock==INVALID_SOCKET)
{
        r=WSAGetLastError();
    closesocket(sock);
    sprintf(sBuf,"Winsock Error:%d",r);
    return Error(_T(sBuf));
}
//设置接收超时6000毫秒
    if(setsockopt(sock,IPPROTO_TCP,SO_RCVTIMEO,(const char FAR*)&iSRTimeOut,sizeof(int))==SOCKET_ERROR)
{
r=WSAGetLastError();
closesocket(sock);
sprintf(sBuf,"Winsock Error:%d",r);
//return Error(_T(sBuf));
}
//设置发送超时6000毫秒
    if(setsockopt(sock,IPPROTO_TCP,SO_SNDTIMEO,(const char FAR*)&iSRTimeOut,sizeof(int))==SOCKET_ERROR)
    {
r=WSAGetLastError();
closesocket(sock);
sprintf(sBuf,"Winsock Error:%d",r);
//return Error(_T(sBuf));
}
//设置非阻塞连接方式
unsigned long ul = 1;
    r = ::ioctlsocket(sock, FIONBIO, (unsigned long*)&ul);
    if(r==SOCKET_ERROR)
{
r=WSAGetLastError();
closesocket(sock);
sprintf(sBuf,"Winsock Error:%d",r);
// return Error(_T(sBuf));
}
//进行连接操作
    switch (m_ProxyType)
    {
case 0:
       sockaddr.sin_addr.s_addr=inet_addr(m_SvrAddr);
   sockaddr.sin_port=htons((unsigned short)m_SvrPort);
   break;
    default:
       sockaddr.sin_addr.s_addr=inet_addr(m_ProxyAddr);
   sockaddr.sin_port=htons((unsigned short)m_ProxyPort);
   break;
    }
    sockaddr.sin_family=AF_INET;
    memset(sockaddr.sin_zero,0,8);
   int iReturn;
    connect(sock,(struct sockaddr*)&sockaddr,sizeof(struct sockaddr_in));
iReturn = ConnectedReady(sock);// 连接延时
if(iReturn == 0)
{
return Error(_T("Connect TimeOut!"));
}
if(iReturn >1)
{
sprintf(sBuf,"Winsock Error:%d",iReturn);
return Error(_T(sBuf));
}
//设置回阻塞模式
unsigned long ul1= 0 ;
    r = ioctlsocket(sock, FIONBIO, (unsigned long*)&ul1);
    if(r==SOCKET_ERROR)
{
r=WSAGetLastError();
closesocket (sock);
sprintf(sBuf,"Winsock Error:%d",r);
return Error(_T(sBuf));
}
说明:进行setsockopt、设置非阻塞模式、一直到最后设置回阻塞模式,都有错误码返回!
功能描述:本来我的程序就是要实现:自己定义一个timeout值,在网络不通或阻塞时,客户端调用connect,最长等待timeout秒。
msn:himming@hotmail.com

 

---------------------------------------------------------------------

http://www.cnblogs.com/BloodAndBone/archive/2012/05/22/2513338.html

 

 

windows下设置socket的connect超时

变相的实现connect的超时,我要讲的就是这个方法,原理上是这样的:
1.建立socket
2.将该socket设置为非阻塞模式
3.调用connect()
4.使用select()检查该socket描述符是否可写(注意,是可写)
5.根据select()返回的结果判断connect()结果
6.将socket设置为阻塞模式(如果你的程序不需要用阻塞模式的,这步就省了,不过一般情况下都是用阻塞模式的,这样也容易管理)

复制代码

// widonws: 默认设置socket TCP client connect为阻塞模式
void TcpConnect(char* strIP, UINT nPort)
{
    struct sockaddr_in serverAddress;
    SOCKET hSocket = NULL;

    hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if( hSocket==INVALID_SOCKET)
    {
        return;
    }

    memset(&serverAddress, 0, sizeof(serverAddress));     
    serverAddress.sin_family      = AF_INET;
    serverAddress.sin_addr.s_addr = inet_addr(strIP);   
    serverAddress.sin_port        = htons((short)nPort);      
    int iTimeOut = 3000;
    setsockopt(hSocket,SOL_SOCKET,SO_RCVTIMEO,(char*)&iTimeOut,sizeof(iTimeOut));
    setsockopt(hSocket,SOL_SOCKET,SO_SNDTIMEO,(char*)&iTimeOut,sizeof(iTimeOut));    

    if( SOCKET_ERROR==connect(hSocket, (sockaddr*)&serverAddress, sizeof(serverAddress)) )
    {        
        closesocket(hSocket);
        DWORD gle = WSAGetLastError();

        return;
    }

    char buff[] = "hello";
    int sl=::send(hSocket,(char*)buff, sizeof(buff), 0);
    if( sl<0 )
    {
        closesocket(hSocket);
        return ;
    }
    closesocket(hSocket);
}

// widonws: 设置socket TCP client connect非阻塞模式
void SockSelect(char* strIP, UINT nPort)
{
    SOCKET/*int*/ sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if(sockfd < 0) 
    {
        return;
    }
    struct sockaddr_in serv_addr;

    //以服务器地址填充结构serv_addr
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = inet_addr(strIP);
    serv_addr.sin_port = htons(nPort);
    int error = -1;
    int len = sizeof(int);
    timeval tm;
    fd_set set;
    unsigned long ul = 1;
    ioctlsocket(sockfd, FIONBIO, &ul); //设置为非阻塞模式
    bool ret = false;
    if( connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) == -1)
    {
        tm.tv_sec  = 3;
        tm.tv_usec = 0;
        FD_ZERO(&set);
        FD_SET(sockfd, &set);
        if( select(sockfd+1, NULL, &set, NULL, &tm) > 0)
        {
            getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (char *)&error, /*(socklen_t *)*/&len);
            if(error == 0) 
                ret = true;
            else 
                ret = false;
        } 
        else 
            ret = false;
    }
    else 
        ret = true;
    ul = 0;
    ioctlsocket(sockfd, FIONBIO, &ul); //设置为阻塞模式
    if(!ret) 
    {
        closesocket( sockfd );
        fprintf(stderr , "Cannot Connect the server!/n");
        return;
    }

    fprintf( stderr , "Connected!/n");

    char buff[] = "hello";
    int sl=::send(sockfd,(char*)buff, sizeof(buff), 0);

    closesocket( sockfd );
}

复制代码

分类: c/c++, VC++

posted on 2013-08-22 18:14 小高 阅读(756) 评论(0)  编辑  收藏 所属分类: C


只有注册用户登录后才能发表评论。


网站导航:
 

导航

<2013年8月>
28293031123
45678910
11121314151617
18192021222324
25262728293031
1234567

统计

常用链接

留言簿(3)

随笔分类(352)

收藏夹(19)

关注的blog

手册

搜索

积分与排名

最新评论

阅读排行榜

评论排行榜