當前位置:首頁 » 操作系統 » linuxsocket超時

linuxsocket超時

發布時間: 2022-12-14 05:42:30

Ⅰ 我想請教linux 下socket 超時設置的問題

舉例:

s=socket();
設置s為non-blocking;
connect(s,..);
FD_SET...;
rc = select(..., 10s);
if (rc == 0) 表示10s超時了。

這個超時的意思是:10s之內,select中所有socket的事件均未產生(如果至少有一個產生,則rc大於0)

注意:這個10s跟connect本身的超時機制完全無關,前者的設置不影響後者。10s後select的返回,表明10s內connect還沒成功,connect可能還在按自己的超時機制(例如慢啟動)嘗試重連(當然它最終也有個超時)。

至於connect本身的超時是否可以設置,可能各系統不一樣。

順便提醒:connect的socket必須是non-blocking類型,否則,connect會阻塞,也就沒必要用select來檢測是否連接成功。另外,那個s要注冊到write類型的fd中,即select的第3個參數中。

其他listen,recv什麼的,完全類似(但listen,recv本身沒有什麼超時概念)。只不過listen的和recv的socket,要注冊到read的fd中。

Ⅱ linux非阻塞socket中select的問題

select是不斷的監聽文件描述符,肯定能探測到它已經關閉了,那麼關閉的fd肯定就得從它的fd_set中退出來哇,退出來了,它自然就不監聽這個fd了,然後就只有等到超時退出了·····我個人的理解,說的好就給個分···呵呵··

Ⅲ 在Linux裡面使用 setsockopt 為套接字設置超時選項 SO_RCVTIMEO 操作成功,可是實際運行時不起作用,為什麼

暈, RCVTIMEO 只有在recv阻塞socket的時候,才有意義。你已經是non-blocking socket了,還設timeout幹啥。

如果你是想要設置 select 的 timeout,應該在調用 select 時候指定timeout如

select(xxx, zzz, sss, mmm, &timeout);

Ⅳ linux socket 求助,總是提示 Connection refused

有時候,寫UDP socket程序的時候,在調用sendto或者recvfrom的時候,會發現有Connection refused錯誤返回,錯誤碼是ECONNREFUSED。對於懂得socket介面但是不很很懂網路的人,可能這根本就不是個問題,他會根據錯誤碼知道遠端沒有這個服務埠,正如socket api的man手冊中描述的那樣: ECONNREFUSED A remote host refused to allow the network connection (typically because it is not running the requested service). 有時候無知真的是一種幸福!但是如果你十分精通TCP/IP棧,那麼就想不通了,UDP既然無連接,怎麼知道遠端的情況呢?UDP不正如協議標准描述的那樣,發出去就不管了嗎?對於接收,沒有數據就一直等,如果設置了NOWAIT,則直接返回EAGAIN,表示稍後再試。不管怎麼說,也不會有ECONNREFUSED這么詳細的信息返回才對啊。 既然UDP不會從對端返回任何錯誤信息,那麼一定有別的什麼返回了,總不能憑空猜測啊。這就涉及到了網路協議設計中的數據平面和控制平面了,對於控制平面的消息,可以是帶內傳輸,也可以是帶外傳輸。對於TCP而言,無疑是帶內傳輸的,因為它本身就是有連接的協議,協議本身會處理任何的錯誤和異常,然而對於UDP而言,因為其設計目的就是保持簡單性,故不再附帶有任何帶內的控制消息邏輯,互聯網上為了彌補這一類協議的控制邏輯的缺失,ICMP協議才顯得尤為重要!實際上,ICMP,根據名稱就可以看出它是一種專門的控制協議,控制和指示IP層發生的事件。 ECONNREFUSED正是ICMP返回的!

Ⅳ linux socket 求助,總是提示 Connection refused

1. 首先那個要加上listen,listen會把socket創建的套接字從CLOSE狀態,轉換到LISTEN狀態
2. err = bind(server_socket, (sockaddr*)&server_addr, sizeof(server_addr));這里強制轉換為什麼可以直接用sockaddr *呢,不應該是struct sockaddr *呢?
3. server_addr.sin_addr.s_addr = inet_addr(SERVER_IP)這里最好還是用inet_pton吧
4.
err = connect(s,(sockaddr*)&server_addr, sizeof(sockaddr));這句你仔細看看,最後一個sizeof裡面的東西。改改差不多了應該,怎麼能編譯不報錯呢,編譯的時候加上-Wall試試

Ⅵ linux下setsockopt設置socket超時

she would watch a show and buy some gifts.

Ⅶ linux下有系統tcp連接超時時間么

可以作為TCP連接的典範:

boolCRemoteLink::Connect()
{
OnDisconnected();//如果已經連接,則斷開

if(!m_bUseProxy)
{

m_iConnStatus=SS_CONNECTING;//正在連接狀態
GNTRACE("開始連接到遠程伺服器[%s][%ld]... ",m_strip.c_str(),m_port);

//建立套接字,准備連接到伺服器
m_socket=::socket(AF_INET,SOCK_STREAM,0);
if(socket<0){
if(m_pCallBack)
m_pCallBack->OnSocketError(SE_CREATE,MSG_SE_CREATE);
returnfalse;
}

//設為非同步操作方式
unsignedlongon=1;
if(::ioctlsocket(m_socket,FIONBIO,&on)<0){
::closesocket(m_socket);
if(m_pCallBack)
m_pCallBack->OnSocketError(SE_CREATE,MSG_SE_CREATE);
returnfalse;
}

sockaddr_inaddr;
memset(&addr,0,sizeof(addr));
addr.sin_family=AF_INET;
addr.sin_addr.s_addr=inet_addr(m_strip.c_str());
addr.sin_port=htons(m_port);

intrt;
rt=::connect(m_socket,(sockaddr*)&addr,sizeof(addr));
if(rt==0){
OnConnected();
returntrue;
}

//==================================================================
timevalto;

//首先建立連接
fd_setwfds;
fd_setefds;
FD_ZERO(&wfds);
FD_ZERO(&efds);

//testshutdowneventeach100ms.
to.tv_sec=0;
//CONNECT_TIMEOUT;
to.tv_usec=100000;

intit=0;
while(!m_meShutdown.Wait(0)&&!m_meConnStop.Wait(0))
{
FD_SET(m_socket,&wfds);
FD_SET(m_socket,&efds);
intn=select(m_socket+1,NULL,&wfds,&efds,&to);

if(n>0){
if(FD_ISSET(m_socket,&wfds))
{
OnConnected();
returntrue;
}
else
{
//interr=::WSAGetLastError();
//constchar*msg=GetLastErrorMessage(err);
GNTRACE("CRemoteLink::Connect:connectionattemptfailed! ");
if(m_pCallBack)
m_pCallBack->OnSocketError(SE_CONN,MSG_SE_CONN);
break;
}
}elseif(n<0){//SelectError
interr=::WSAGetLastError();
constchar*msg=GetLastErrorMessage(err);
GNTRACE("CRemoteLink::Connect:SelectError.[%d]-%s ",err,msg);
if(m_pCallBack)
m_pCallBack->OnSocketError(err,msg);
break;
}
else
{
it+=100;
if(it>30000)//連接超時--(30S)
{
GNTRACE("CRemoteLink::Connect:Timeout. ");
if(m_pCallBack)
m_pCallBack->OnSocketError(SE_TIMEOUT,MSG_SE_TIMEOUT);
break;
}
}
}
if(m_meConnStop.Wait(0))
{
GNTRACE("連接過程進行時被取消。 ");
}
}
else
{
//通過代理伺服器連接

Ⅷ linux socket阻塞recv怎麼返回

recv是socket編程中最常用的函數之一,在阻塞狀態的recv有時候會返回不同的值,而對於錯誤值也有相應的錯誤碼,分別對應不同的狀態,下面是我針對常見的幾種網路狀態的簡單總結。
首先阻塞接收的recv有時候會返回0,這僅在對端已經關閉TCP連接時才會發生。
而當拔掉設備網線的時候,recv並不會發生變化,仍然阻塞,如果在這個拔網線階段,socket被關掉了,後果可能就是recv永久的阻塞了。
所以一般對於阻塞的socket都會用setsockopt來設置recv超時。
當超時時間到達後,recv會返回錯誤,也就是-1,而此時的錯誤碼是EAGAIN或者EWOULDBLOCK,POSIX.1-2001上允許兩個任意一個出現都行,所以建議在判斷錯誤碼上兩個都寫上。
如果socket是被對方用linger為0的形式關掉,也就是直接發RST的方式關閉的時候,recv也會返回錯誤,錯誤碼是ENOENT
還有一種經常在代碼中常見的錯誤碼,那就是EINTER,意思是系統在接收的時候因為收到其他中斷信號而被迫返回,不算socket故障,應該繼續接收。但是這種情況非常難再現,我嘗試過一邊一直在不停的發信號,一邊用recv接收數據,也沒有出現過。這種異常錯誤我附近只有一個朋友在用write的時候見到過一次,但是總是會有概率出現的,所以作為完善的程序必須對此錯誤進行特殊處理。
一般設置超時的阻塞recv常用的方法都如下:
while(1)
{
cnt = (int)recv(m_socket, pBuf,RECVSIZE, 0);
if( cnt >0 )
{
//正常處理數據
}
else
{
if((cnt<0) &&(errno == EAGAIN||errno == EWOULDBLOCK||errno == EINTR)) //這幾種錯誤碼,認為連接是正常的,繼續接收
{
continue;//繼續接收數據
}
break;//跳出接收循環
}
}
阻塞與非阻塞recv返回值沒有區分,都是 <0 出錯 =0 連接關閉 >0 接收到數據大小。

Linux環境下,須如下定義:struct timeval timeout = {3,0};
//設置發送超時
setsockopt(socket,SOL_SOCKET,SO_SNDTIMEO,(char *)&timeout,sizeof(struct timeval));
//設置接收超時
setsockopt(socket,SOL_SOCKET,SO_RCVTIMEO,(char *)&timeout,sizeof(struct timeval));

Ⅸ socket超時什麼意思

你好,這分為兩種情況。
Socket.connect連接超時有二種情況:
1.由於網路的問題,TCP/IP三次握手時間>timeout的設置時間。這在國外訪問weibo時,並且網路環境極差的情況下有可能發生。
解決的辦法:調大socket.connect方法中的timeout參數值,比如50s,linux默認最高是70s,如果超過70s沒有意義,linux會採用70s.
但是當調大之後,發現不到10s就報timeout exception。
通過國外的機器ping api.weibo.com發現unreachable。
說明客戶端在傳輸層之下的網路層就發現連個Syn的報文都發不出去,更不用說三次握手了,客戶端直接失敗並拋timeout exception。
經驗:在connection timeout診斷的第一步應該是ping一下確認網路層沒有問題。
註:客戶端設置了timeout,但並不會等到超時才返回異常。客戶端只要第一時間發現連接失敗,就會拋timeout exception。

2.如果timeout設置的時間足夠,但是由於伺服器端的處理能力較差,比如緩沖連接隊列較小,而應用層的處理能力沒有連接緩沖快,導致緩沖連接占滿,而拒絕新的連接。
在服務端因為連接隊列占滿而拒絕服務的期間,客戶端的通過TCP協議重試三次。每次的時間翻倍。
如果三次時間的累加<timeout參數值且能連接上,屬於正常情況,表示隊列騰出空位放當前連接。
如果三次時間的累加<timeout參數值且未能連接上,則客戶端會立刻拋出timeout exception,而不等timeout到期才拋。

1.讀寫超時
read超時設置有意義,在伺服器處理能力差,但最終會響應的情況下,可以將客戶端的等待響應時間設長一些。如果太長的話,由於客戶端使用的是BIO的方式,線程會一直阻塞在IO而導致掛起。當客戶端的處理能力明顯快於服務端,這樣掛起的線程會很多。
不管客戶端還是伺服器端,當有很多線程阻塞時,對機器的性能都會影響。我在weibo的論壇上看到有人在read timed out後,將soTimeout的時間設為100s。這是很危險的,新浪的伺服器一旦崩潰,自己的伺服器也會由於大量線程積壓崩潰。
因為線程在掛起之後,它掌握的資源並不會釋放,比如內存,直到阻塞完成。同時大量線程的掛起就意味著系統要做大量上下文的恢復並調度執行。
解決辦法:
如果客戶端使用NIO的方式,如果服務端的響應能標出客戶端的請求,則線程在客戶端請求之後,完全可以把請求放入一個BlockQueue,然後利用Future或Wait/Notify等機制在帶著請求標志的響應返回的時候,喚想隊列中的請求接著處理,從而實現非同步處理,可以用少量線程服務大量請求。
同樣,如果伺服器端可以使用NIO做到請求每線程處理,而不是連接每線程,可以大大減少線程掛起導致資源的浪費,NIO適用於連接很多,請求很少的場合。另外,Commet又稱為伺服器推技術,它的主要特點是長連接。避免客戶端低效的請求輪詢。主要用於聊天室,WEIBO,因為連接多,請求不一定多,同樣也適合在伺服器端使用NIO
註:read timeout異常時,並不需要ping遠程機器,因為它是輔助定位connection timeout,如果ping不通,肯定是conneciton timeout而不會到read timeout。read timeout exception不會導致連接中斷。為重試提供了機會。

2.write超時一般不象connection timeout和read timeout可以在客戶端顯示調值,TCP有寫重傳的概念,一般8m內會重試,否則,直接斷開連接。
如果對您有幫助,還望採納。

Ⅹ Linux如何清空Socket緩沖區

socket不是這么接收數據的 由於socket是以數據流的形式發送數據,接收方不知道對方一次性發送了多少數據,也能保證對方一次性發送的數據能在同一刻接收到,所以Receive方法是這么工作的: 接受一個byye[]類型的參數作為緩沖區,在經過一定的時間後把接收到的數據填充到這個緩沖區裡面,並且返回實際接收到數據的長度,這個實際接收到的數據長度有可能為0(沒有接收到數據)、大於0小於緩沖區的長度(接收到數據,但是沒有我們預期的多)、等於緩沖區的長度(說明接收到的數據大於等於我們預期的長度)。 每次接收緩沖區都用同一個byte[] byteMessage,並且你沒有檢查接收到的數據長度,所以第一次你接收到的數據是123456,第二次你只接收到了8,但是緩沖區裡面還有23456,所以加起來就是823456了。 socket接收緩沖區的大小有講究,設置大了接收起來慢,因為它要等盡可能多的數據接收到了再返回;設置小了需要重復多次調用接收方法才能把數據接收完,socket有個屬性,標識了系統默認的接收緩沖區大小,可以參考這個! 還有就是用recv讀取,但是由於不知道緩存里有多少數據,如果是阻塞模式,到最後必然等到超時才知道數據已經讀取完畢,這是個問題。 另一個是用fgetc,通過返回判斷是否是feof: whlie (1) { a=fgetc(f);if (feof(f)) break;//… b=fgetc(f);if (feof(f)) break;//…}當然,我不知道讀取完畢後最後一次調用fgetc會不會堵塞,需要測試。 在非阻塞模式下,我們用recv就可以輕松搞定了,但是阻塞模式下,由於我們不知道緩沖區有多少數據,不能直接調用recv嘗試清除。 使用一個小小的技巧,利用select函數,我們可以輕松搞定這個問題: select函數用於監視一個文件描述符集合,如果集合中的描述符沒有變化,則一直阻塞在這里,直到超時時間到達;在超時時間內,一旦某個描述符觸發了你所關心的事件,select立即返回,通過檢索文件描述符集合處理相應事件;select函數出錯則返回小於零的值,如果有事件觸發,則返回觸發事件的描述符個數;如果超時,返回0,即沒有數據可讀。 重點在於:我們可以用select的超時特性,將超時時間設置為0,通過檢測select的返回值,就可以判斷緩沖是否被清空。通過這個技巧,使一個阻塞的socket成了『非阻塞』socket. 現在就可以得出解決方案了:使用select函數來監視要清空的socket描述符,並把超時時間設置為0,每次讀取一個位元組然後丟棄(或者按照業務需要進行處理,隨你便了),一旦select返回0,說明緩沖區沒數據了(「超時」了)。 struct timeval tmOut;tmOut.tv_sec = 0;tmOut.tv_usec = 0;fd_set fds;FD_ZEROS(&fds);FD_SET(skt, &fds); int nRet; char tmp[2]; memset(tmp, 0, sizeof(tmp)); while(1) { nRet= select(FD_SETSIZE, &fds, NULL, NULL, &tmOut);if(nRet== 0) break;recv(skt, tmp, 1,0);} 這種方式的好處是,不再需要用recv、recvfrom等阻塞函數直接去讀取,而是使用select,利用其超時特性檢測緩沖區是否為空來判斷是否有數據,有數據時才調用recv進行清除。 有人說同樣可以用recv和socket的超時設置去清空啊,這個沒錯,但是你需要直接對socket描述符設置超時時間,而為了清空數據而直接修改socket描述符的屬性,可能會影響到其他地方的使用,造成系統奇奇怪怪的問題,所以,不推薦使用。

熱點內容
用什麼dns伺服器地址快 發布:2025-05-15 04:52:59 瀏覽:26
手機端so反編譯 發布:2025-05-15 04:50:55 瀏覽:610
linuxlamp安裝 發布:2025-05-15 04:50:45 瀏覽:578
sqlplus緩存區怎麼設置 發布:2025-05-15 04:50:44 瀏覽:858
shell腳本環境變數 發布:2025-05-15 04:45:18 瀏覽:693
安卓nba2k18什麼時候出 發布:2025-05-15 04:38:42 瀏覽:393
王者安卓轉蘋果為什麼顯示失敗 發布:2025-05-15 04:35:49 瀏覽:18
手機優酷緩存視頻格式 發布:2025-05-15 04:13:45 瀏覽:210
公益電影分鏡頭腳本插畫 發布:2025-05-15 04:08:37 瀏覽:961
數據壓縮編碼 發布:2025-05-15 03:58:44 瀏覽:726