如下演示程式,程式目的是:
先準備好乙個serversocket,監聽埠8880,
然後建乙個clientsocket(受限於業務需要,必須在serversocket準備好後再建client),也必須繫結同一埠8880,
問題是:為什麼對clientsocket bind(port 8880)時,會報錯eaddrinuse?我已經啟用了so_reuseaddr。
為了方便於大家試執行,我把**簡化的沒有其他庫依賴,只需g++ -o demo demo.cpp即可執行。
c/c++ code
#include
<
stdio.h
>
#include
<
netdb.h
>
#include
<
errno.h
>
#include
<
string
.h>
#include
<
unistd.h
>
#include
<
linux
/tcp.h
>
intsockdemo()
intmain(
intargc,
char
*argv)
如果真如各位所說,下面的現象該做何解釋??示例**中,只要去掉listen(serv, somaxconn)一句即可正常執行。
使用 so_reuseport 這個吧。so_reuseaddr和so_reuseport
so_reuseaddr提供如下四個功能:
so_reuseaddr允許啟動乙個監聽伺服器並**其眾所周知埠,即使以前建立的將此埠用做他們的本地埠的連線仍存在。這通常是重啟監聽伺服器時出現,若不設定此選項,則bind時將出錯。
so_reuseaddr允許在同一埠上啟動同一伺服器的多個例項,只要每個例項**乙個不同的本地ip位址即可。對於tcp,我們根本不可能啟動**相同ip位址和相同埠號的多個伺服器。
so_reuseaddr允許單個程序**同一埠到多個套介面上,只要每個**指定不同的本地ip位址即可。這一般不用於tcp伺服器。
so_reuseaddr允許完全重複的**:當乙個ip位址和埠繫結到某個套介面上時,還允許此ip位址和埠**到另乙個套介面上。一般來說,這個特性僅在支援多播的系統上才有,而且只對udp套介面而言(tcp不支援多播)。
so_reuseport選項有如下語義:
此選項允許完全重複**,但僅在想**相同ip位址和埠的套介面都指定了此套介面選項才性。
如果被**的ip位址是乙個多播位址,則so_reuseaddr和so_reuseport等效。
使用這兩個套介面選項的建議:
在所有tcp伺服器中,在呼叫bind之前設定so_reuseaddr套介面選項;
當編寫乙個同一時刻在同一主機上可執行多次的多播應用程式時,設定so_reuseaddr選項,並將本組的多播位址作為本地ip位址**。
#define so_reuseport 15
使用這兩個套介面選項的建議:
在所有tcp
伺服器中
,在呼叫bind
之前設定
so_reuseaddr
套介面選項;
當編寫乙個同一時刻在同一主機上可執行多次的多播應用程式時
,設定so_reuseaddr選項,
並將本組的多播位址作為本地ip
位址**。
if (setsockopt(
fd, sol_socket, so_reuseaddr,
(const void *)&noptval , sizeof(int)) < 0)
...附
q:編寫
tcp/sock_stream
服務程式時,
so_reuseaddr
到底什麼意思?
a:這個套接字選項通知核心,如果埠忙,但
tcp狀態位於
time_wait
,可以重用埠。如果埠忙,而
tcp狀態位於其他狀態,重用埠時依舊得到乙個錯誤資訊,指明
"位址已經使用中
"。如果你的服務程式停止後想立即重啟,而新套接字依舊使用同一埠,此時
so_reuseaddr
選項非常有用。必須意識到,此時任何非期望資料到達,都可能導致服務程式反應混亂,不過這只是一種可能,事實上很不可能。
乙個套接字由相關五元組構成,協議、本地位址、本地埠、遠端位址、遠端埠。
so_reuseaddr
僅僅表示可以重用本地本地位址、本地埠,整個相關五元組還是唯一確定的。所以,重啟後的服務程式有可能收到非期望資料。必須慎重使用
so_reuseaddr
選項。【2】
【1】
】以下部落格對這個問題進行了對答式的解答:
】
但是這就引出了另外的乙個問題,就是設定這個屬性後允許乙個套接字上同時有兩個應用程式進行監聽,那系統究竟會將資料傳送給哪乙個程式呢?系統會將資料首先交給監聽ip最確定的應用程式。例如應用程式a在呼叫監聽函式時設定的屬性是addr.sin_addr.s_addr := inaddr_any;而另外的乙個應用程式b則監聽的位址為addr.sin_addr.s_addr := inet_addr(pchar(smainip));同時這兩個應用程式監聽的埠都是相同的,這是系統接收到資料後會首先交給b然後再交給a。因此一般為了程式安全我們會禁止這種情況的發生。因此需要設定下面的so_exclusiveaddruse屬性。
網路程式設計設定TTL
最近遇到乙個問題,領導讓我查一下關於多播的ttl配置的問題,我也是看了diam之後才知道的原來ttl可以通過程式設計來實現,說起來網路程式設計能力欠佳啊 ttl是 time to live的縮寫,該欄位指定ip包被路由器丟棄之前允許通過的最大網段數量。ttl是ipv4包頭的乙個8 bit欄位.在ip...
linux多執行緒程式設計2 屬性的設定
屬性設定 屬性結構為pthread attr t,它同樣在標頭檔案 usr include pthread.h中定義 include pthread attr t attr pthread t tid 初始化屬性值,均設為預設值 pthread attr init attr pthread attr...
設定鍵盤屬性
所以回到 main 函式中,繼續走,下乙個該執行 keyboard set repeat 函式了。59 60 set the keyboard repeat rate to maximum.unclear why this 61 is done here this might be possible...