异步模式的socket在connect之后怎么知道connect成功还是失败 c#socket异步连接后怎样判断连接是否成功
socket\u7f16\u7a0b\u4e2dconnect\u5931\u8d25\u7684\u539f\u56e0\u539f\u56e0\u5f88\u591a\uff0c\u6bd4\u5982\u8d85\u65f6\uff0cURL\u4e0d\u5bf9\uff0c\u7aef\u53e3\u4e0d\u5bf9\u7b49\u7b49\u3002
\u662f\u4f60\u7684\u4ee3\u7801\u6709\u95ee\u9898\u4e48\uff1f
\u5982\u679c\u662f\u5c31\u628a\u4ee3\u7801\u8d34\u4e0a\u6765\u3002
//\u8fd9\u662f\u4f8b\u5b50\uff0c\u4f60\u53c2\u8003\u53c2\u8003private int connToServer(string hostip, int hostport,int ctimeout) { IPEndPoint remoteEp = new IPEndPoint(IPAddress.Parse(hostip),hostport); try { connDone.Reset(); //\u5f00\u59cb\u8fde\u63a5 cliSock.BeginConnect(remoteEp, new AsyncCallback(connCallBack), cliSock); connDone.WaitOne(ctimeout, false); if (!cliSock.Connected) { //\u8fde\u63a5\u8d85\u65f6 return CONNTIMEOUT; } //\u8fde\u63a5\u6210\u529f return 0; } catch (SocketException ex) { //\u8fde\u63a5\u5931\u8d25 cliSock.Close(); return CONNTIMEOUT; } catch (Exception ex) { //\u8fde\u63a5\u5931\u8d25 cliSock.Close(); return CONNTIMEOUT; } } private void connCallBack(IAsyncResult ar) { Socket s = (Socket)ar.AsyncState; try { s.EndConnect(ar); isConnected = s.Connected; } catch (Exception ex) { isConnected = false; //\u53d1\u751f\u9519\u8bef return; } finally { connDone.Set(); } }
m_strServerIP = strServerIP;m_nPort = nPort;
while( true )
{
// 创建套接字
m_socket = socket(AF_INET,SOCK_STREAM,0);
if( m_socket == INVALID_SOCKET )
break;
// 设置为非阻塞模式
DWORD ul = 1;
if( 0 != ioctlsocket( m_socket, FIONBIO, &ul) )
break;
// 将UNICODE的IP地址转换为多字节字符的IP地址
char szServerIP[16] = { 0 };
if( WideCharToMultiByte( CP_ACP,0,m_strServerIP,m_strServerIP.GetLength(),szServerIP,sizeof(szServerIP),NULL,NULL ) == 0 )
break;
// 连接指定的IP地址和端口
SOCKADDR_IN sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(m_nPort);
sin.sin_addr.s_addr = inet_addr( szServerIP );
if( ! ( SOCKET_ERROR == connect( m_socket, (SOCKADDR *)&sin, sizeof(sin)) && WSAGetLastError() == WSAEWOULDBLOCK ) )
break;
// 异步connect不会等待就直接返回了,用select的方式来判断connect是否成功,select会阻塞,只到connect连接成功或失败后select才返回
fd_set fs_read;
FD_ZERO( &fs_read );
FD_SET( m_socket,&fs_read );
fd_set fs_write;
fs_write.fd_count = 1;
fs_write.fd_array[0] = m_socket;
fd_set fs_error;
fs_error.fd_count = 1;
fs_error.fd_array[0] = m_socket;
int ret = select( 0,&fs_read,&fs_write,&fs_error,NULL );
if( ret == SOCKET_ERROR )
break;
// 判断socket句柄是否可写
if( !FD_ISSET( m_socket,&fs_write ) )
break;
int optval = -1;
int optlen = sizeof(optval);
ret = getsockopt( m_socket,SOL_SOCKET,SO_ERROR,(char*)(&optval),&optlen );
if( ret != 0 || optval != 0)
break;
// 直到这里connect才是真正成功
// 创建监听线程收到消息的事件句柄
m_wsaEvent = WSACreateEvent();
if( m_wsaEvent == WSA_INVALID_EVENT )
break;
// 给监听线程的消息到达事件句柄配置要通知的事件类型
if( WSAEventSelect( m_socket,m_wsaEvent,FD_READ|FD_WRITE|FD_CONNECT|FD_CLOSE ) != 0 )
break;
// 创建通知监听线程退出的事件句柄
m_wsaClose = WSACreateEvent();
if( m_wsaClose == WSA_INVALID_EVENT )
break;
// 创建消息事件监听线程
DWORD dwThreadId;
m_hThreadEvent = CreateThread( NULL, 0, ThreadProc_SocketEvent, this, 0, &dwThreadId );
if( m_hThreadEvent == NULL )
break;
// 创建定时发送心跳包的事件句柄
m_hEventHeartbeat= CreateEvent( NULL,TRUE,FALSE,NULL );
if( m_hEventHeartbeat == NULL )
break;
// 创建定时发送心跳包的线程
m_hThreadHeartbeat = CreateThread( NULL,0,ThreadProc_Heartbeat,this,0, &dwThreadId );
if( m_hThreadHeartbeat == NULL )
break;
// 全部创建成功,返回TRUE
return TRUE;
}
绛旓細if( ! ( SOCKET_ERROR == connect( m_socket, (SOCKADDR *)&sin, sizeof(sin)) && WSAGetLastError() == WSAEWOULDBLOCK ) )break;// 寮傛connect涓嶄細绛夊緟灏辩洿鎺ヨ繑鍥炰簡锛岀敤select鐨勬柟寮忔潵鍒ゆ柇connect鏄惁鎴愬姛锛宻elect浼氶樆濉烇紝鍙埌connect杩炴帴鎴愬姛鎴栧け璐ュ悗select鎵嶈繑鍥 fd_set fs_read;FD_ZERO( &...
绛旓細socket鐨勫悓姝ュ拰寮傛锛屼富瑕佹槸鎸囧鐞嗘湇鍔$澶勭悊socket鐨妯″紡锛屾帴鏀舵秷鎭拰澶勭悊娑堟伅鐨勫悓姝ュ拰寮傛锛屽尯鍒涓嬶細1銆佸悓姝ョ殑socket锛屾湇鍔$鍦ㄦ帴鏀跺埌涓涓猻ocket璇锋眰涔嬪悗锛屽繀椤诲鐞嗗畬骞惰繑鍥炵粰瀹㈡埛绔箣鍚庯紝鎵嶅鐞嗕笅涓涓猻ocket璇锋眰銆2銆寮傛鐨剆ocket锛屾湇鍔$鍦ㄦ敹鍒颁竴涓猻ocket璇锋眰涔嬪悗锛屽皢璇ocket璇锋眰浜ょ粰鍏朵粬绾跨▼澶勭悊锛岀劧鍚...
绛旓細socket鐨勫悓姝ュ拰寮傛锛屼富瑕佹槸鎸囧鐞嗘湇鍔$澶勭悊socket鐨妯″紡锛屾帴鏀舵秷鎭拰澶勭悊娑堟伅鐨勫悓姝ュ拰寮傛銆傚悓姝ョ殑socket锛屾湇鍔$鍦ㄦ帴鏀跺埌涓涓猻ocket璇锋眰涔嬪悗锛屽繀椤诲鐞嗗畬骞惰繑鍥炵粰瀹㈡埛绔箣鍚庯紝鎵嶅鐞嗕笅涓涓猻ocket璇锋眰銆寮傛鐨剆ocket锛屾湇鍔$鍦ㄦ敹鍒颁竴涓猻ocket璇锋眰涔嬪悗锛屽皢璇ocket璇锋眰浜ょ粰鍏朵粬绾跨▼澶勭悊锛岀劧鍚庣户缁帴鏀朵笅涓涓猻ock...
绛旓細socket鐨鍚屾涓寮傛涔嬮棿鐨勬晥鐜囧樊璺濆緢澶с俿ocket鐨勬剰鎬濇槸涓ぎ澶勭悊鍣ㄧ殑鎻掑骇銆備綅浜庝富鏉夸笂銆備富鏉挎槸瀹夎鍦ㄤ富鏈轰腑鏈澶х殑涓鍧楀嵃鍒风數璺澘锛屾槸涓鍙扮數鑴戠殑鏍稿績閮ㄥ垎锛屽畠鏄腑澶鐞嗗櫒銆佸唴瀛樸佸悇绉嶆帶鍒惰姱鐗囥佽緭鍏ヨ緭鍑烘帶鍒跺拰鍚勭鎵╁睍妲藉崱鐨勫熀鏈緷鎵樸備富鏉挎ц兘鐩存帴褰卞搷涓绘澘涓婂叾瀹冮儴浠舵ц兘鐨勫彂鎸ワ紝涓嶅悓鐨勪腑澶鐞嗗櫒搴旇閰嶅鐩稿簲...
绛旓細鐢变簬socket鍑芥暟鍦╝ccept銆乻end鐨勬椂鍊欙紝鐢变簬缃戠粶绛夊師鍥狅紝涓嶈兘寰堝揩鐨勫畬鎴愶紝鍥犳浼氬彂鐢熻繘绋嬮樆濉烇紙鐩村埌socket鍑芥暟鎵ц瀹屾垚锛屼笅闈㈢殑鍑芥暟鎵嶄細鎵ц锛夛紝鍥犳锛屽線寰鏄柊寤轰竴涓繘绋嬶紝璁╀粬鎵цsocket杩囩▼锛屼富绾跨▼绠$悊鐢ㄦ埛鐣岄潰锛屼笉浼氬嚭鐜癠I鍋囨鐨勬儏鍐点傚洜姝わ紝鎵璋撳紓姝ョ殑socket锛屽氨鏄湪鍙﹀涓涓繘绋嬩腑瀹炵幇鐨勩
绛旓細鍦ㄦ甯哥殑宸ヤ綔妯″紡(CPU涓嶈秴棰)涓嬶紝鐩墠涓嶅皯涓绘澘鑺墖缁勪篃鏀寔鍐呭瓨寮傛宸ヤ綔妯″紡锛屼緥濡侷ntel 910GL鑺墖缁勶紝浠呬粎鍙敮鎸533MHz FSB鍗133MHz鐨凜PU澶栭锛屼絾鍗村彲浠ユ惌閰嶅伐浣滈鐜囦负133MHz鐨凞DR 266銆佸伐浣滈鐜囦负166MHz鐨凞DR 333鍜屽伐浣滈鐜囦负200MHz鐨凞DR 400姝e父宸ヤ綔(娉ㄦ剰姝ゆ椂鍏禖PU澶栭133MHz涓嶥DR 400鐨勫伐浣滈鐜200...
绛旓細鍩轰簬C#鐨剆ocket缂栫▼鐨凾CP寮傛瀹炵幇涓銆佹憳瑕 鏈瘒鍗氭枃闃愯堪鍩轰簬TCP閫氫俊鍗忚鐨勫紓姝ュ疄鐜般備簩銆佸疄楠屽钩鍙 Visual Studio 2010涓夈佸紓姝ラ氫俊瀹炵幇鍘熺悊鍙婂父鐢ㄦ柟娉3.1 寤虹珛杩炴帴 鍦ㄥ悓姝妯″紡涓,鍦ㄦ湇鍔″櫒涓婁娇鐢ˋccept鏂规硶鎺ュ叆杩炴帴璇锋眰,鑰屽湪瀹㈡埛绔垯浣跨敤Connect鏂规硶鏉ヨ繛鎺ユ湇鍔″櫒銆傜浉瀵瑰湴,鍦寮傛妯″紡涓,鏈嶅姟鍣ㄥ彲浠ヤ娇鐢˙eginAccept鏂规硶鍜孍nd...
绛旓細灏辩敤鍒颁簡鎴戜滑鐨寮傛浼犺緭銆傚紓姝ヤ紶杈撶殑鍘熺悊鏄傚湪a绔緱鍒拌繖涓猻ocket瀵硅薄浠ュ悗骞朵笉鏄洿鎺ュ幓鎺ユ敹鏁版嵁鑰屾槸寤虹珛涓涓洖璋冨嚱鏁般傚洖璋冨嚱鏁版槸鐢辩郴缁熺淮鎶ょ殑銆備粬鍦ㄦ寚瀹氱殑鏃堕棿鑷姩鍘绘壂鎻忔暟鎹瓨鍌ㄥ尯銆傚亣濡傛湁鏁版嵁浠栧氨鎶婃暟鎹瓨鍌ㄥ埌鎸囧畾鐨勫瓧鑺傛暟缁勪腑銆備笉鐢ㄧ敤鎴疯嚜宸卞幓鍏冲績銆傞偅涔堝悓姝ヤ笌寮傛鍒嗗埆搴旂敤浜庝粈涔堟儏鍐靛憿锛熷亣濡傜敤鎴鐨剆ocke...
绛旓細鍦寮傛RecVing鏂规硶涓湁涓ょ偣鍙互鏀硅繘锛1锛夊鍔犲紓甯稿鐞嗭紝鐩殑鏄細鍗充娇鍙戠敓寮傚父涔熶繚璇Socket鑳芥甯稿伐浣溿2锛夎皟鐢 EndAceept杩斿洖鐨勬槸姝e湪涓庡鎴风杩炴帴鐨剆ockt private static void RecVing(IAsyncResult Result){ //閫氳繃 result 鑾峰彇socket銆傚湪杩欎釜socket涓婁綘鍚姩浜咮eginAccept鎿嶄綔 Socket socket = Result...
绛旓細// remote device is "host.contoso.com".IPHostEntry ipHostInfo = Dns.Resolve("host.contoso.com");IPAddress ipAddress = ipHostInfo.AddressList[0];IPEndPoint remoteEP = new IPEndPoint(ipAddress, port);// Create a TCP/IP socket.Socket client = new Socket(AddressFamily.InterNetwork,Soc...