socket 程式設計的埠和位址復用

2021-08-18 22:26:09 字數 2505 閱讀 5715

int opt = 1;

if(setsockopt(sockfd, sol_socket,so_reuseaddr, (const

void *) &opt, sizeof(opt)))

so_reuseaddr允許啟動乙個監聽伺服器並**其眾所周知埠,即使以前建立的將此埠用做他們的

本地埠的連線仍存在。這通常是重啟監聽伺服器時出現,若不設定此選項,則bind時將出錯。

so_reuseaddr允許在同一埠上啟動同一伺服器的多個例項,只要每個例項**乙個不同的本地ip位址

即可。對於tcp,我們根本不可能啟動**相同ip位址和相同埠號的多個伺服器。

so_reuseaddr允許單個程序**同一埠到多個套介面上,只要每個**指定不同的本地ip位址即

可。這一般不用於tcp伺服器。

口**到另乙個套介面上。一般來說,這個特性僅在支援多播的系統上才有,而且只對udp套

介面而言(tcp不支援多播)。

此選項允許完全重複**,但僅在想**相同ip位址和埠的套介面都指定了此套介面選項才行。

如果被**的ip位址是乙個多播位址,則so_reuseaddr和so_reuseport等效。

在所有tcp伺服器中,在呼叫bind之前設定so_reuseaddr套介面選項;
q:編寫 tcp/sock_stream 服務程式時,so_reuseaddr到底什麼意思?

a:這個套接字選項通知核心,如果埠忙,但tcp狀態位於 time_wait ,可以重用埠。如果埠忙,

而tcp狀態位於其他狀態,重用埠時依舊得到乙個錯誤資訊,指明"位址已經使用中"。如果你的服務程式停止

後想立即重啟,而新套接字依舊使用同一埠,此時so_reuseaddr 選項非常有用。必須意識到,此時任何

非期望資料到達,都可能導致服務程式反應混亂,不過這只是一種可能,事實上很不可能。

其實這個問題在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上,但每個socket繫結的ip位址不同。這和2很相似,區別請看unpv1。

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

原始碼:[cpp]view plain

copy

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#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*/

}  }  

Linux之socket程式設計 資料IO和復用

在linux之socket程式設計 網路程式設計基礎中介紹了socket程式設計中的一些框架性函式。可以保證網路資料能夠正常地到達使用者,這篇部落格主要講解網路通訊資料的互動,即網路資料的收發以及io模型。include include ssize t send int sockfd,const v...

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

其實這個問題在richard stevens的 unix網路程式設計指南 卷一里有很詳細的 解答 中文版p166 168頁 這裡我只是寫幾個基本的例子來驗證這個問題。首先宣告乙個問題 當兩個socket的address和port相衝突,而你又想重用地 址和埠,則舊的socket和新的socket都要...

SOCKET繫結時,埠和位址為0解析

在socket程式設計中,要做伺服器時我們通常要使用bind函式來繫結乙個ip和port。但有時在使用bing函式時發現,addr中的ip或者port為0的情況。在 unix網路程式設計 這本書中提到 如果乙個tcp客戶或者伺服器未曾呼叫bind 乙個埠,當呼叫connect或listen時,核心就...