日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

TCP解决connect函数的超时问题

發布時間:2024/8/23 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 TCP解决connect函数的超时问题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
在一個TCP套接口被設置為非阻塞之后調用connect,connect會立即返回EINPROGRESS錯誤,表示連接操作正在進行中,但是仍未完成;同時TCP的三路握手操作繼續進行;在這之后,我們可以調用select來檢查這個鏈接是否建立成功;非阻塞connect有三種用途:
1.我們可以在三路握手的同時做一些其它的處理.connect操作要花一個往返時間完成,而且可以是在任何地方,從幾個毫秒的局域網到幾百毫秒或幾秒的廣域網.在這段時間內我們可能有一些其他的處理想要執行;

2.由于我們使用select來等待連接的完成,因此我們可以給select設置一個時間限制,從而縮短connect的超時時間.在大多數實現中,connect的超時時間在75秒到幾分鐘之間.有時候應用程序想要一個更短的超時時間,使用非阻塞connect就是一種方法;

  • timeval?tm;??
  • fd_set?set;??
  • unsigned?long?ul?=?1;??
  • ioctlsocket(sock,?FIONBIO,?&ul);?//設置為非阻塞模式??
  • bool?ret?=?false;??
  • if?(connect(...)?==?-1)??
  • {??
  • ????tm.tv_set??=?TIME_OUT_TIME;??
  • ????tm.tv_uset?=?0;??
  • ????FD_ZERO(&set);??
  • ????FD_SET(sock,?&set);??
  • ??
  • ????if?(select(sock,?NULL,?&set,?NULL,?&tm)?>?0)??
  • ????{??
  • ????????getsockopt(sockfd,?SOL_SOCKET,?SO_ERROR,?&error,?(socklen_t?*)&len);??
  • ????????if?(error?==?0)??
  • ????????{??
  • ????????????ret?=?true;??
  • ????????}??
  • ????????else??
  • ????????{??
  • ????????????ret?=?false;??
  • ????????}??
  • ????}??
  • ????else??
  • ????{??
  • ????????ret?=?false;??
  • ????}??
  • }??
  • else??
  • {??
  • ????ret?=?true;??
  • }??
  • ul?=?0;??
  • ioctlsocket(sock,?FIONBIO,?&ul);?//設置為阻塞模式??
  • if(!ret)???
  • {??
  • ????close(?sockfd?);??
  • ????printf(stderr?,?"Cannot?Connect?the?server!/n");??
  • ????return;??
  • }??
  • printf(?stderr?,?"Connected!/n");??
  • 代碼思路:?

    1.建立socket
    ?2
    .將該socket設置為非阻塞模式
    ?3
    .調用connect()
    ?4
    .使用select()檢查該socket描述符是否可寫

    ?5.根據select()返回的結果判斷connect()結果
    ?6
    .將socket重設置為阻塞模式

    ?

    所謂阻塞函數,是指其完成指定的任務之前不允許程序調用另一個函數,在Windows下還會阻塞本線程消息的發送。

    所謂非阻塞函數,是指操作啟動之后,如果可以立即得到結果就返回結果,否則返回表示結果需要等待的錯誤信息,不等待任務完成函數就返回。

    首先,異步函數是非阻塞函數;

    其次,獲取遠地信息的數據庫函數是阻塞函數(因此,WinSock提供了其異步版本);

    下面對具體函數做解釋:

    [cpp]??view plain?copy
  • int?select(??
  • ??__in??????????int?nfds,//本參數忽略,僅起到兼容作用??
  • ??__in_out??????fd_set*?readfds,//指向一組等待可讀性檢查的套接口,可為NULL??
  • ??__in_out??????fd_set*?writefds,//指向一組等待可寫性檢查的套接口,可為NULL??
  • ??__in_out??????fd_set*?exceptfds,//指向一組等待錯誤檢查的套接口,可為NULL??
  • ??__in??????????const?struct?timeval*?timeout//select()最多等待時間,對阻塞操作則為NULL??
  • );??
  • ??
  • ??
  • ???
  • ?

    ?本函數用于確定一個或多個套接口的狀態。對每一個套接口,調用者可查詢它的可讀性、可寫性及錯誤狀態信息。用fd_set結構來表示一組等待檢查的套接口

    ?readfds參數標識等待可讀性檢查的套接口。如果該套接口正處于監聽listen()狀態,則若有連接請求到達,該套接口便被標識為可讀,這樣一個accept()調用保證可以無阻塞完成。對其他套接口而言,可讀性意味著有排隊數據供讀取。或者對于SOCK_STREAM類型套接口來說,相對于該套接口的虛套接口已關閉,于是recv()或recvfrom()操作均能無阻塞完成

    writefds參數標識等待可寫性檢查的套接口。如果一個套接口正在connect()連接(非阻塞),可寫性意味著連接順利建立。如果套接口并未處于connect()調用中,可寫性意味著send()和sendto()調用將無阻塞完成。〔但并未指出這個保證在多長時間內有效,特別是在多線程環境中〕。

    exceptfds參數標識等待帶外數據存在性或意味錯誤條件檢查的套接口。請注意如果設置了SO_OOBINLINE選項為假FALSE,則只能用這種方法來檢查帶外數據的存在與否。對于SO_STREAM類型套接口,遠端造成的連接中止和KEEPALIVE錯誤都將被作為意味出錯。如果套接口正在進行連接connect()(非阻塞方式),則連接試圖的失敗將會表現在exceptfds參數中。

    返回值:
    ?? select()調用返回處于就緒狀態并且已經包含在fd_set結構中的描述字總數;如果超時則返回0;否則的話,返回SOCKET_ERROR錯誤,應用程序可通過WSAGetLastError()獲取相應錯誤代碼。


    總結

    以上是生活随笔為你收集整理的TCP解决connect函数的超时问题的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。