socket位址和埠重用(造成bind出錯)

2021-07-03 04:36:38 字數 3014 閱讀 3993

其實這個問題在richard stevens的《unix網路程式設計指南》卷一里有很詳細的

解答(中文版p166-168頁)。這裡我只是寫幾個基本的例子來驗證這個問題。

首先宣告乙個問題:當兩個socket的address和port相衝突,而你又想重用地

址和埠,則舊的socket和新的socket都要已經被設定了so_reuseaddr特性,只

有兩者之一有這個特性還是有問題的。

so_reuseaddr可以用在以下四種情況下。

(摘自《unix網路程式設計》卷一,即unpv1)

1、當有乙個有相同本地位址和埠的socket1處於time_wait狀態時,而你啟

動的程式的socket2要占用該位址和埠,你的程式就要用到該選項。

2、so_reuseaddr允許同一port上啟動同一伺服器的多個例項(多個程序)。但

每個例項繫結的ip位址是不能相同的。在有多塊網絡卡或用ip alias技術的機器可

以測試這種情況。

3、so_reuseaddr允許單個程序繫結相同的埠到多個socket上,但每個soc

ket繫結的ip位址不同。這和2很相似,區別請看unpv1。

4、so_reuseaddr允許完全相同的位址和埠的重複繫結。但這只用於udp的

多播,不用於tcp。

例子1:測試上面第一種情況。

#include in

.h>

#include

#include

#include

#include <

string

.h>

#define

maxline 100

intmain(

intargc,

char

** argv)

bzero(&servaddr,

sizeof

(servaddr));

servaddr.sin_family=af_inet;

servaddr.sin_addr.s_addr=htonl(inaddr_any);

servaddr.sin_port=htons(port);

if( setsockopt(listenfd, sol_socket, so_reuseaddr, &flag, len) == -

1)

if( bind(listenfd,(

struct

sockaddr*)&servaddr,

sizeof

(servaddr)) ==

-1)

else

printf("bind call ok!/n");

if( listen(listenfd,5) == -1)

for(;;) if

( fork() == 0)

/*child process*/

close(connfd);

exit(0);

/* end parent*/

} }

測試:編譯為f1-9d程式,放到乙個自己path環境變數裡的某個路徑裡,例如$ho

me/bin,執行f1-9d,然後telnet localhost 10013看結果。

2、第二種情況我沒有環境測,所以就不給測試程式了,大家有條件的可以自己寫

乙個來測試一下。

3、測試第三種情況的程式

#include in

.h>

#include

#include

#include

#include <

string

.h>

#define

maxline 100

intmain(

intargc,

char

** argv) if

( (fd2=socket(af_inet,sock_stream,0)) == -1)

bzero(&servaddr1,

sizeof

(servaddr1));

bzero(&servaddr2,

sizeof

(servaddr2));

servaddr1.sin_family=af_inet;

servaddr2.sin_family=af_inet;

if( inet_pton(af_inet, "127.0.0.1", &servaddr1.sin_addr) <= 0) if

( inet_pton(af_inet, "128.160.1.230", &servaddr2.sin_addr) <= 0)

servaddr1.sin_port=htons(port);

servaddr2.sin_port=htons(port);

if( setsockopt(fd1, sol_socket, so_reuseaddr, &flag, len) == -1) if

( setsockopt(fd2, sol_socket, so_reuseaddr, &flag, len) == -1) if

( bind(fd1,(

struct

sockaddr*)&servaddr1,

sizeof

(servaddr1)) == -1) if

( bind(fd2,(

struct

sockaddr*)&servaddr2,

sizeof

(servaddr2)) == -1)

printf("bind fd1 and fd2 ok!/n");

/*put other process here*/

getchar();

exit(0);

/* end */}

4、由於第四種情況只用於udp的多播,和tcp的使用沒多大關係,所以就不寫測試

例子了。自己有興趣的可以寫。

以上的程式都是在linux下編譯通過的。也可以在其他unix平台執行。

埠重用開啟cmdshell

要重用的埠是tomcat的預設http埠8080。源 include pragma comment lib,ws2 32.lib define listen port 8080 int main 此時,已經啟動tomcat,可以通過來訪問tomcat主頁。執行此程式時,如果沒有重用埠,繫結到8080...

學習筆記 socket關於埠重用的學習

這兩天想搭建乙個c2c伺服器的模型,一開始是想用c寫,結果c的各種細節寫的人太煩躁了,就換成了python,原來n百行的 瞬間變成了幾十行,世界一下子就清淨了 這是後話,此文主要是記錄一下埠重用的問題。之前寫socket經常在除錯時候,每次重啟服務端都會在bind時候報錯 埠被占用 這是因為bind...

套接字 實現埠重用

假如埠被socket使用過,並且利用socket.close 來關閉連線,但此時埠還沒有釋放,要經過乙個time wait的過程之後才能使用,這是tnn的相當煩銀的,為了實現埠的馬上覆用,可以選擇setsockopt 函式來達到目的。以下是網上找到的一篇文章的一小段相關例子,試用之後,相當有效果,特...