超時設定方法( the way to set timeout )
Tips:
In the connection between the server and the client. Sometimes there may have some timeout. Today , we used our own method to realise a series of timeout function , including read_timeout , write_timeout , accept_timeout and connect_timeout which is the most difficult in four of them. We need to understand the different processing method of the timeout.
Client :
/************************************************************************ > filename : echocli.c > Author: ma6174 > Mail: [email protected] > Created Time: Thu 29 Oct 16:38:57 2015 ************************************************************************/ #include <fcntl.h> #include <stdio.h> #include <sys/socket.h> #include <string.h> #include <arpa/inet.h> #include <stdlib.h> #include <unistd.h> #include <errno.h> #include <signal.h> #define ERR_EXIT(m) \ do \ {\ perror(m) ;\ exit(EXIT_FAILURE) ;\ }while(0) /* * read timeout -- * the function to test read timeout , not including read function. * fd : file descriptor * wait_senconds : the time to wait timeout,0 means that doesn't test timeout * success(not timeout) return 0 ; failed return -1 with timeout return -1 * errno = ETIMEOUT */ int read_timeout ( int fd , unsigned int wait_seconds ) { int ret ; ret = 0 ; if ( wait_seconds > 0 ) { fd_set read_fdset ; struct timeval timeout ; FD_ZERO (&read_fdset ) ; FD_SET ( fd , &read_fdset ) ; timeout.tv_sec = wait ( wait_seconds ) ; timeout.tv_usec = 0 ; do { ret = select ( fd + 1 , &read_fdset , NULL , NULL , &timeout ) ; }while( ret < 0 && EINTR == errno ) ; // this occasion is interrupted by signal if ( 0 == ret ) { ret = -1 ; errno = ETIMEDOUT ; } else if ( 1 == ret ) // fd creats an readable event { ret = 0 ; } } return ret ; } /** * write_timeout write timeout function , no including write * fd : file descriptor * wait_seconds : the time to wait timeout , if 0 = wait senconds means that it doesn't test timeout * success(not timeout) return 0 ; failed return -1 with timeout return -1 */ int write_timeout ( int fd , unsigned int wait_seconds ) { int ret ; ret = 0 ; if ( wait_seconds > 0 ) { fd_set write_fdset ; struct timeval timeout ; FD_ZERO ( &write_fdset ) ; FD_SET ( fd , &write_fdset ) ; timeout.tv_sec = wait_seconds ; timeout.tv_usec = 0 ; do { ret = select ( fd + 1 , NULL ,&write_fdset , NULL , &timeout ) ; }while(ret < 0 && EINTR == errno ) ; if ( 0 == ret ) { ret = -1 ; errno = ETIMEDOUT ; } else if ( 1 == ret ) { ret = 0 ; } } return ret ; } /** * accept timeout with the accept function * fd : socket * addr : output parameter , return peer addr * wait_seconds : wait the time of timeout , if 0 = timeout means that it's the normal occassion * success(not timeout) return the connected socket; when it's timeout return -1 withe errno = ETIMEOUT */ int accept_timeout ( int fd , struct sockaddr_in *addr , unsigned int wait_seconds ) { int ret ; ret = 0 ; socklen_t addrlen = sizeof(struct sockaddr_in ) ; if ( wait_seconds > 0 ) { fd_set accept_fdset ; struct timeval timeout ; FD_ZERO ( &accept_fdset ) ; FD_SET ( fd , &accept_fdset ) ; timeout.tv_sec = wait_seconds ; timeout.tv_usec = 0 ; do { ret = select ( fd + 1 , &accept_fdset , NULL ,NULL , &timeout ) ; }while(ret < 0 && EINTR == errno ) ; if ( -1 == ret ) { return -1 ; } else if ( 0 == ret ) { errno = ETIMEDOUT ; return -1 ; } } if ( NULL != addr ) { ret = accept ( fd , ( struct sockaddr*) addr , &addrlen ) ; } else { ret = accept ( fd , NULL , NULL ) ; } if ( -1 == ret ) { ERR_EXIT("accept") ; } return ret ; } /** * activate_nonblock * fd : file descriptor */ void activate_nonblock ( int fd ) { int ret ; int flags = fcntl ( fd , F_GETFL ) ; //fcnt1 get the flag of fd. if ( -1 == flags ) { ERR_EXIT("fcnt1") ; } flags |= O_NONBLOCK ; // add non_block model ret = fcntl ( fd , F_SETFL , flags ) ; if ( -1 == ret ) { ERR_EXIT ("fcnt1") ; } } /** * deactivate_nonblack * fd : file descriptor */ void deactivate_nonblock ( int fd ) { int ret ; int flags = fcntl ( fd , F_GETFL ) ; if ( -1 == flags ) { ERR_EXIT ("fcnt1") ; } flags &= ~ O_NONBLOCK ; // remove nonblock to the block model ret = fcntl ( fd , F_SETFL , flags ) ; if ( -1 == ret ) { ERR_EXIT ("fcnt1") ; } } /** * connect_timout -connect * fd : socket * addr: the peer address that we need to connect * wait_seconds : the time which is the timeout, if 0 = wait_seconds it means normal. * sucdess (it is not timeout ) return 0 ; failed return -1 with errno = ETIMEOUT */ int connect_timeout ( int fd , struct sockaddr_in *addr , unsigned int wait_seconds ) { int ret ; socklen_t addrlen = sizeof(struct sockaddr_in ); if ( wait_seconds > 0 ) { activate_nonblock(fd) ; } ret = connect ( fd , ( struct sockaddr*)addr , addrlen ) ; if ( ret < 0 && EINPROGRESS == errno ) { printf ("AAAAAAAAAAAAA\n") ; fd_set connect_fdset ; struct timeval timeout ; FD_ZERO ( &connect_fdset ) ; FD_SET ( fd , &connect_fdset ) ; timeout.tv_sec = wait_seconds ; timeout.tv_usec = 0 ; do { // once connected , the socket is writable ret = select ( fd + 1 , NULL , &connect_fdset , NULL , &timeout ) ; }while( ret < 0 && EINTR == errno ) ; if ( 0 == ret ) // timeout { ret = -1 ; errno = ETIMEDOUT ; } else if ( ret < 0 ) // ret < 0 && EINTR != errno which means there is a mistake in socket. { return -1 ; } else if ( 1 == ret ) { /* ret = 1 means two occassion , one is the connection is successful. the other is that the connection has some mistakes. When there is a mistake in the socket , the failed information(but this kind of mistake would not influence select function) wouldn's save in the errno , we need to use the getsockopt to get it. */ printf ("BBBBBBBBBBB\n") ; int err ; socklen_t socklen = sizeof(err) ; int sockopt_ret = getsockopt ( fd , SOL_SOCKET , SO_ERROR , &err , &socklen ) ; if ( -1 == sockopt_ret ) { return -1 ; } if ( 0 == err ) // no error , the connection is established. { printf ("DDDDDDDDDDDDDDD\n") ; ret = 0 ; } else // the socket has a mistake { printf ("CCCCCCCCCCCC\n") ; errno = err ; ret = -1 ; } } } if ( wait_seconds > 0 ) { deactivate_nonblock(fd) ; } return ret ; } int main (void) { int sock ; if ( ( sock = socket ( PF_INET , SOCK_STREAM , IPPROTO_TCP ) ) < 0 ) { ERR_EXIT("socket") ; } struct sockaddr_in servaddr ; memset ( &servaddr , 0 , sizeof(servaddr) ) ; servaddr.sin_family = PF_INET ; servaddr.sin_port = htons(5188) ; servaddr.sin_addr.s_addr = inet_addr("127.0.0.1") ; int ret = connect_timeout ( sock , &servaddr , 5 ) ; // timeout = 5 if ( -1 == ret && ETIMEDOUT == errno ) { printf ("timeout ...\n") ; return 1 ; } else if ( -1 == ret ) { ERR_EXIT("connect_timeout") ; } struct sockaddr_in localaddr ; socklen_t addrlen = sizeof(localaddr) ; if ( getsockname ( sock , ( struct sockaddr*) &localaddr , &addrlen ) < 0 ) { ERR_EXIT ("getsockname") ; } printf ("ip = %s port = %d\n" , inet_ntoa(localaddr.sin_addr) , ntohs(localaddr.sin_port) ) ; return 0 ; }
Server :
/************************************************************************ > filename: echocli.c > Author: ma6174 > Mail: [email protected] > Created Time: Thu 29 Oct 16:38:57 2015 ************************************************************************/ #include <sys/select.h> #include <sys/types.h> #include <signal.h> #include <stdio.h> #include <sys/socket.h> #include <string.h> #include <arpa/inet.h> #include <stdlib.h> #include <unistd.h> #include <errno.h> #include <sys/wait.h> #define ERR_EXIT(m) \ do \ {\ perror(m) ;\ exit(EXIT_FAILURE) ;\ }while(0) int main(void) { int listenfd ; if ( (listenfd = socket(PF_INET , SOCK_STREAM , 0 ) ) < 0 ) { ERR_EXIT("socket") ; } struct sockaddr_in servaddr ; memset ( &servaddr , 0 , sizeof(servaddr) ) ; servaddr.sin_family = AF_INET ; servaddr.sin_port = htons(5188) ; servaddr.sin_addr.s_addr = htonl(INADDR_ANY) ; int on = 1 ; if ( setsockopt ( listenfd , SOL_SOCKET , SO_REUSEADDR , &on , sizeof(on) ) < 0 ) { ERR_EXIT("setsockopt") ; } if ( bind ( listenfd , ( struct sockaddr* ) &servaddr , sizeof(servaddr) ) < 0 ) { ERR_EXIT("bind") ; } if ( listen ( listenfd , SOMAXCONN ) < 0 ) { ERR_EXIT("listen") ; } struct sockaddr_in peeraddr ; socklen_t peerlen ; peerlen = sizeof(peeraddr) ; int conn ; if ( ( conn = accept ( listenfd , ( struct sockaddr* ) &peeraddr , &peerlen ) ) < 0 ) { ERR_EXIT("accept") ; } printf ("ip = %s port = %d\n" , inet_ntoa(peeraddr.sin_addr) , ntohs(peeraddr.sin_port) ) ; return 0 ; }
相關推薦
超時設定方法( the way to set timeout )
Tips: In the connection between the server and the client. Sometimes there may have some timeout. Today , we used our own method to reali
IE/Firefox每次重新整理時自動檢查網頁更新,無需手動清空快取的設定方法(轉)
1.在firefox的位址列上輸入about:config回車 2.找到browser.cache.check_doc_frequency選項,雙擊將3改成1儲存即可。 那麼這個選項每個值都是什麼含義的。請看下面的解釋: 0: Once per session 每個程序一次 每次啟動Fire
Go語言學習之sync包(臨時物件池Pool、互斥鎖Mutex、等待Cond)(the way to go)
golang的特點就是語言層面支援併發,並且實現併發非常簡單,只需在需要併發的函式前面新增關鍵字go。 但是如何處理go併發機制中不同goroutine之間的同步與通訊,golang 中提供了sync包來解決相關的問題,當然還有其他的方式比如channel,原子操作atomic等等,這裡先
利用FutureTask進行超時設定方法
public class Test { public static void main(String[] args) { ExecutorService executor = Executors.newSingleThreadExecutor(); Futur
101343A On The Way to Lucky Plaza
題目地址 題意:有m個商店,Alaa想買k個巧克力,每個商店只能買一塊巧克力,Alaa進每個商店的概率是一樣的,問你在買第k個巧克力的時候是在第n家店的概率是多少,然後答案化成分數取模的形式。 其實挺簡單的,就是坑有點。。。 我們可以知道要求的概率為C(n−1,
LandGrey-On the way to become a hacker
0x01: 前臺指令碼檢測副檔名—繞過 原理 當用戶在客戶端選擇檔案點選上傳的時候,客戶端還沒有向伺服器傳送任何訊息,就對本地檔案進行檢測來判斷是否是可以上傳的型別,這種方式稱為前臺指令碼檢測副
eclipse中java程式碼格式化設定方法 (zz)
由於之前習慣了Java的程式碼格式化樣式,即如下圖1的第一種程式碼格式,而看第二種程式碼格式時感覺程式碼很亂,總找不到“{ }”對稱的感覺。eclipse自動格式化程式碼的快捷方式是Ctrl+Shift+F ,下面將通過設定eclipse來達到第一種程式碼樣式。
Facebook's PyTorch plans to light the way to speedy workflows for Machine Learning • DEVCLASS
Facebook's development department has finished a first release candidate for v1 of its PyTorch project – just in time for the first conference dedicated to
A new theory for phantom limb pain points the way to more effective treatment
Phantom limb pain is a poorly understood phenomenon, in which people who have lost a limb can experience severe pain, seemingly located in that missing pa
Graphene on the way to superconductivity
A complicated option for superconductivity In April 2018, a group at MIT, USA, showed that it is possible to generate a form of superconductivity in a sys
Java中httpClient中的三種超時設定小結(轉)
在Apache的HttpClient包中,有三個設定超時的地方: /* 從連線池中取連線的超時時間*/ ConnManagerParams.setTimeout(params, 1000); /*連線超時*/ HttpConnectionParams.s
MongoDB使用使用者名稱密碼驗證的設定方法(windows下)
之前整理的mongo基本語法都是在沒有使用者名稱密碼驗證的條件下測試的,因為mongo與mysql不同,它安裝的時候預設是沒有許可權控制的額,也就是說任何人,只要知道了host和port都可以登陸資料庫並操作。 如果想要設定使用者,需要自己另行配置。 一開始按照網上
ON THE WAY TO GEEK
寫在最前的三點: 1、所謂圖的遍歷就是按照某種次序訪問圖的每一頂點一次僅且一次。 2、實現bfs和dfs都需要解決的一個問題就是如何儲存圖。一般有兩種方法:鄰接矩陣和鄰接表。這裡為簡單起 見,均採用鄰接矩陣儲存,說白了也就是二維陣列。 3、本文章的小測試部分的測試例項是下圖
2016.9.1Project The way to東京奧運會スダート
哼哼哼。。。 このprojectの意味は。。。。。東京オリンピックまで。。。ずっと。。。。 A題!!!!!! これはただのオリンピックの道ではない、わたしのために、お姫様のために、東だいの修士のために 次回のオリンピック。。。。この目で見る! この4年の道、頑張ります 簡
Qt控制元件隨視窗大小變化的設定方法(QTDesigner)
1 新建窗體(Dialog、MainWindow或Widget都行); 2 拖一個控制元件到窗體上(任何控制元件都可以:layout、button、或check box); 3 在窗體空白處右鍵→佈局→柵格佈局(G),即可; 4 如果第二步新增的layout控制元件,有時,
Go實戰--go中編碼轉換(The way to go)
生命不止,繼續 go go go !!! 編碼問題在每種語言中都會遇到,尤其對於中國的碼農來說,更是常見的問題,因為我們的漢字有一點點特別。所以需要一些自己的編碼,這就需要進行一些適當的轉換。 例如,C++開發中,我們經常會用到wstring與string的
Go實戰--實現簡單的restful api(The way to go)
生命不止,繼續 go go go !!! 今天跟大家介紹一下如何使用go建立一套restful api,我們依託於開源庫gorilla/mux。 let’s go~~ 何為RESTful API A RESTful API is an app
MATLAB中呼叫Weka設定方法(轉)及示例
MATLAB命令列下驗證Java版本命令 version -java 配置MATLAB呼叫Java庫 Finish Java codes. Create Java library file, i.e., .jar file. Put crea
Android Wi-Fi MIMO/SISO設定方法(基於高通平臺)
adb remount adb pull /system/etc/wifi/WCNSS_qcom_cfg.ini We change gEnable2x2 in WCNSS_qcom_cfg.
Go實戰--go中使用base64加密(The way to go)
生命不止,繼續 Go go go !!! base64加密你一點也不會陌生,Base64是網路上最常見的用於傳輸8Bit位元組程式碼的編碼方式之一,大家可以檢視RFC2045~RFC2049,上面有MIME的詳細規範。Base64編碼可用於在HTTP環境下傳遞