使用setsockopt進行埠復用

2021-10-09 21:10:58 字數 1664 閱讀 6005

使用ctrl+c終止程式:

終止client.c ----->終止server.c  ------>啟動server.c  -----> 啟動client.c 不會出現問題

終止server.c ----->終止client.c  ------>啟動server.c ----->啟動client.c   會出現問題

使用 netstat -apn|grep 埠號  檢視埠號的占用情況

先終止server.c的時候,埠號沒有被釋放。當再啟動server.c的時候,就會報錯埠被占用,錯誤資訊如下:

bind函式會報錯,address already in use

進一步分析,這是由於伺服器端先關閉的話,伺服器會處於2msl時長的time_wait狀態(程式終止了,但是tcp協議層的連線沒有完全斷開),埠仍然在占用,故會報該錯誤。

先關閉客戶端程式則不會出現這種問題,則是因為,雖然客戶端先關閉後,客戶端也會處於2msl時長的time_wait狀態,客戶端的埠也會被占用,但是,因為客戶端程式中並沒有呼叫bind函式,即客戶端的繫結的埠號是系統隨機分配的,當再次啟動客戶端時,客戶端又會被重新分配新的埠號,不會出現埠被占用的情況。

當先終止server.c後,檢視網路連線狀態,發現,伺服器端的狀態是fin_wait2.,客戶端的狀態是close_wait

等待一會後,發現伺服器端消失了,只剩下客戶端的狀態了。 

這是因為,server.c終止,會傳送fin給client.c,client傳送ack給server.c後,自身變為close_wait,而伺服器端變為fin_wait2.  客戶端此時並沒有關閉,不會向server.c傳送fin,狀態也不會改變。

我們在先關閉伺服器程式後,想立即重啟伺服器程式,不希望等待2msl時長,那如何解決這個問題呢?這就用到了埠復用

使用setsockopt()函式對socket進行埠復用。

#include /* see notes */

#include int getsockopt(int sockfd, int level, int optname,

void *optval, socklen_t *optlen);

int setsockopt(int sockfd, int level, int optname,

const void *optval, socklen_t optlen);

int opt=1;

setsockopt(listenfd,sol_socket, so_reuseaddr,

&opt, sizeof(opt);

將so_reuseaddr的值賦值為1,則表示生效,賦值為0,則無效。 

放在socket函式之後,bind函式之前。

此時終止server.c後,再重啟server.c,網路狀態仍然為time_wait,但是不會報錯,程式能夠正常執行。

使用ROS進行ARM端與PC端通訊

終於在zynq上跑起了ros,接下來最令人關心的就是能否使用ros使arm端和pc端進行通訊了,我按照wiki上的教程進行了實驗,基本上是沒有問題的,只是需要修改一下arm端和pc端的hosts檔案。1 實驗環境 zynq ubuntu 12.04 groovy pc ubuntu 12.04 fu...

使用MENTOHUST代替銳捷客戶端進行校園網撥號

這個很多人都會,因為用到linux的話,撥號上網必定是要解決的事情。總不能整天拿個無線路由器上網咖?而且你不會刷路由也是無濟於事 長話短說,一針見血,以下是用mentohust上網的步驟 1.在windows下複製銳捷客戶端目錄下的 8021.exe libeay32.dll ssleay32.dl...

移動端 使用REM進行的響應式布局

工具viewtorem px轉換到rem 自動預處理 rem的定義 rem是相對於根元素來設定字型大小的,這樣就意味著,我們只需要在根元素確定乙個參考值,在根元素中設定多大的字型,這完全可以根據您自己的需求。rem與em px的區別 px 畫素,比較精確的單位,但不好做響應式布局 em 以父節點fo...