1. 程式人生 > >Linux網路程式設計之套接字選項設定

Linux網路程式設計之套接字選項設定

轉自 http://blog.csdn.net/chenjin_zhong/article/details/7268939

1.介紹

在Linux網路程式設計中,有時需要設定地址複用,允許傳送廣播包,將主機加入某個多播組,設定傳送與接收緩衝區的大小,設定傳送與接收的超時時間,將套接字繫結到某個介面上,傳送TCP探測包檢視客戶端是否保持連線等,這些都需要對套接字選項進行設定.而對套接字選項進行操作的主要有以下兩個函式,setsockopt與getsockopt. 這兩個函式不僅能夠操作套接字層,而且能夠操作IP層與TCP層.

2.相關函式

#include <sys/types.h>

#include <sys/socket.h>

int getsockopt(int s,int level,int optname,void*optval,socklen_t *optlen);

引數:

s-套接字描述符

level-選項所在的層,主要有SOL_SOCKET(套接字層),IPPROTO_IP(IP選項),IPPROTO_TCP(TCP選項).

optname-選項名

optval-所操作的緩衝區,即引數緩衝區

optlen-傳入引數的最大長度的指標(返回引數的實際長度)

返回值:

函式執行成功返回0,失敗返回-1.

int setsockopt(int s,int level,int optname,const void*optval,socklen_t optlen);

引數:

s-套接字描述符

level-套接字所在的層

optname-套接字選項名

optval-所操作的緩衝區指標

optlen-所傳入引數的實際長度

返回值:

函式執行成功返回0,失敗返回-1.

套接字的一些選項值如下表所示:

level Optname get set 說明 標誌 資料型別
SOL_SOCKET SO_BROADCAST y y 允許傳送廣播資料報 y int
SO_DEBUG y y 使能除錯跟蹤 y int
SO_DONTROUTE y y 旁路路由表查詢 y int
SO_ERROR y 獲取待處理錯誤並消除 int
SO_KEEPALIVE y y 週期性測試連線是否存活 y int
SO_LINGER y y 若有資料待發送則延遲關閉 linger{}
SO_OOBINLINE y y 讓接收到的帶外資料繼續線上存放 y int
SO_RCVBUF y y 接收緩衝區大小 int
SO_SNDBUF y y 傳送緩衝區大小 int
SO_RCVLOWAT y y 接收緩衝區低潮限度 int
SO_SNDLOWAT y y 傳送緩衝區低潮限度 int
SO_RCVTIMEO y y 接收超時 timeval{}
SO_SNDTIMEO y y 傳送超時 timeval{}
SO_REUSEADDR y y 允許重用本地地址 y int
SO_REUSEPORT y y 允許重用本地地址 y int
SO_TYPE y 取得套介面型別 int
SO_USELOOPBACK y y 路由套介面取得所傳送資料的拷貝 y int
IPPROTO_IP IP_HDRINCL y y IP頭部包括資料 y int
IP_OPTIONS y y IP頭部選項 見後面說明
IP_RECVDSTADDR y y 返回目的IP地址 y int
IP_RECVIF y y 返回接收到的介面索引 y int
IP_TOS y y 服務型別和優先權 int
IP_TTL y y 存活時間 int
IP_MULTICAST_IF y y 指定外出介面 in_addr{}
IP_MULTICAST_TTL y y 指定外出TTL u_char
IP_MULTICAST_LOOP y y 指定是否回饋 u_char
IP_ADD_MEMBERSHIP y 加入多播組 ip_mreq{}
IP_DROP_MEMBERSHIP y 離開多播組 ip_mreq{}
IPPROTO_ICMPV6 ICMP6_FILTER y y 指定傳遞的ICMPv6訊息型別 icmp6_filter{}
IPPROTO_IPV6 IPV6_ADDRFORM y y 改變套介面的地址結構 int
IPV6_CHECKSUM y y 原始套介面的校驗和欄位偏移 int
IPV6_DSTOPTS y y 接收目標選項 y int
IPV6_HOPLIMIT y y 接收單播跳限 y int
IPV6_HOPOPTS y y 接收步跳選項 y int
IPV6_NEXTHOP y y 指定下一跳地址 y sockaddr{}
IPV6_PKTINFO y y 接收分組資訊 y int
IPV6_PKTOPTIONS y y 指定分組選項 見後面說明
IPV6_RTHDR y y 接收原路徑 y int
IPV6_UNICAST_HOPS y y 預設單播跳限 int
IPV6_MULTICAST_IF y y 指定外出介面 in6_addr{}
IPV6_MULTICAST_HOPS y y 指定外出跳限 u_int
IPV6_MULTICAST_LOOP y y 指定是否回饋 y u_int
IPV6_ADD_MEMBERSHIP y 加入多播組 ipv6_mreq{}
IPV6_DROP_MEMBERSHIP y 離開多播組 ipv6_mreq{}
IPPROTO_TCP TCP_KEEPALIVE y y 控測對方是否存活前連線閒置秒數 int
TCP_MAXRT y y TCP最大重傳時間 int
TCP_MAXSEG y y TCP最大分節大小 int
TCP_NODELAY y y 禁止Nagle演算法 y int
TCP_STDURG y y 緊急指標的解釋 y int

3.套接字選項設定例項

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <linux/in.h>
#include <unistd.h>
#include <netinet/tcp.h>

//獲取與設定套接字選項的函式
/**
int getsockopt(int s,int level,int optname,void*optval,socklen_t *optlen);
int setsockopt(int s,int level,int optname,const void*optval,socklen_t optlen);
s:表示要獲取或者是設定的套接字描述符
level:協議所在的層
optname:選項名
optval:getsockopt指向用於儲存返回選項值的緩衝區,setsockopt指向設定引數緩衝區
optlen:getsockopt用於傳入引數時表示optval的最大長度,傳出引數時表示optval的實際長度。對於setsockopt表示optval的實際長度
**/
//定認一個共用體用於儲存結果,由於返回值具有不同的型別所以必須用共用體
typedef union optval{
   int val;
   struct linger linger;
   struct timeval tv;
   unsigned char str[16];
   

}val;
static val optval;
//資料型別的定義
typedef enum valtype{
  VALINT,//int 型別
  VALLINGER,//struct linger型別
  VALTIMEVAL,//struct timeval型別
  VALUCHAR,//字串
  VALMAX,//錯誤型別
}valtype;
//儲存套接字選項的結構
typedef struct sopts{
  int level;//套接字選項級別
  int optname;//套接字選項名稱 
  char*name;//套接字名稱
  valtype valtype;//套接字返回引數型別

}sopts;
//套接字陣列
sopts sockopts[]={
  {SOL_SOCKET,SO_BROADCAST,"SO_BROADCAST",VALINT},//是否支援廣播
  {SOL_SOCKET,SO_DEBUG,"SO_DEBUG",VALINT}, //是否支援TCP除錯
  {SOL_SOCKET,SO_DONTROUTE,"SO_DONTROUTE",VALINT},//是否需要路由
  {SOL_SOCKET,SO_ERROR,"SO_ERROR",VALINT},//返回錯誤資訊
  {SOL_SOCKET,SO_KEEPALIVE,"SO_KEEPALIVE",VALINT},//是否支援自動探測TCP連線
  {SOL_SOCKET,SO_LINGER,"SO_LINGER",VALLINGER},//是否支援TCP關閉模式
  {SOL_SOCKET,SO_OOBINLINE,"SO_OOBINLINE",VALINT},//是否支援帶外資料與普通資料一起傳送
  {SOL_SOCKET,SO_RCVBUF,"SO_RECVBUF",VALINT},//設定接收緩衝區大小
  {SOL_SOCKET,SO_SNDBUF,"SO_SNDBUF",VALINT},//設定傳送緩衝區大小
  {SOL_SOCKET,SO_SNDTIMEO,"SO_SNDTIMEO",VALTIMEVAL},//設定傳送資料的超時時間
  {SOL_SOCKET,SO_RCVTIMEO,"SO_RCVTIMEO",VALTIMEVAL},//設定接收資料的超時時間
  {SOL_SOCKET,SO_RCVLOWAT,"SO_RCVLOWAT",VALINT},//設定接收緩衝區的最小位元組數
  {SOL_SOCKET,SO_SNDLOWAT,"SO_SNDLOWAT",VALINT},//設定傳送緩衝區的最小位元組數
  {SOL_SOCKET,SO_REUSEADDR,"SO_REUSERADDR",VALINT},//是否允許埠重用
  {SOL_SOCKET,SO_TYPE,"SO_TYPE",VALINT},//套接字型別
  {SOL_SOCKET,SO_BINDTODEVICE,"SO_BINDTODEVICE",VALUCHAR},//是否將套接字繫結到指定埠
  {SOL_SOCKET,SO_PRIORITY,"SO_PRIORITY",VALINT},//設定套接字的優先級別
  {IPPROTO_IP,IP_HDRINCL,"IP_HDRINCL",VALINT},//使用者是否自己填寫IP頭部
  {IPPROTO_IP,IP_MULTICAST_TTL,"IP_MULTICAST_TTL",VALUCHAR},//多播的最大跳數
  {0,0,NULL,VALMAX}

};
static void display(sopts *sockopt,int len,int err);
//獲得套接字選項值
int main(int argc,char*argv[]){
 int err=-1;
 int len=0;
 int i=0;
 int s=socket(AF_INET,SOCK_STREAM,0);
//首先設定套接字選項資訊,然後再返回套接字選項,先用setsockopt,再用getsockopt
//設定廣播選項
int broadcast=1;
err=setsockopt(s,SOL_SOCKET,SO_BROADCAST,&broadcast,sizeof(broadcast));//broadcast指標指向緩衝區,緩衝區儲存的是允許廣播選項的值,值的長度為&len
if(err){
  perror("setsockopt error");
}
//設定可除錯選項
int debug=1;//核心程式跟蹤此套接字上的接收與傳送資料,並將資料放到一個環形緩衝區,通過trpt檢視,僅支援TCP
err=setsockopt(s,SOL_SOCKET,SO_DEBUG,&debug,sizeof(debug));
if(err){
   printf("debug error\n");
}
//SO_KEEPALIVE用於探測TCP連線是否保持,主要使用在長時間沒有資料響應的TCP連線,如TELNET客戶端長時間不使用,這需要伺服器去探測對方是否活動
int keepalive=10;
err=setsockopt(s,SOL_SOCKET,SO_KEEPALIVE,&keepalive,sizeof(keepalive));
if(err){
  printf("keepalive error");
}
//SO_LINGER選項
/**
主要來設定TCP連線關閉時,使用者緩衝區怎麼處理
struct linger{
int l_onoff; 是否設定延遲關閉
int l_linger;  超時時間
}
如果l_onoff=0,表示沒有使用系統預設的close套接字行為,close函式會立即返回,在可能的情況下儘量傳送緩衝區內的資料,但是使用者沒有辦法知道緩衝區內的資料是否已經完全被髮送,即不確定性
如果l_onoff=1,l_linger表示關閉連線的超時時間,l_linger為非0時,表示超時的秒數,會在超時之前儘量傳送資料,檢查close函式的返回值,如果傳送成功,close返回0,否則緩衝區內的任何資料將會被丟失,返回EWOULDBLOCK.
如果l_onoff=1,l_linger=0,表示立刻關閉,緩衝區內的資料將會丟失。
**/
//設定超時間為60秒
struct linger l;
l.l_onoff=1;//延遲關閉
l.l_linger=60;
err=setsockopt(s,SOL_SOCKET,SO_LINGER,&l,sizeof(l));
if(err){
  perror("SO_LINGER ERROR");
}
//帶外資料指的是那些緊急的資料,TCP優先發送帶外資料,這些資料使用特殊的通道來接收。如果採用SO_OOBINLINE表示在普通資料流中接收帶外數
int oobinline=1;
err=setsockopt(s,SOL_SOCKET,SO_OOBINLINE,&oobinline,sizeof(oobinline));
if(err){
  perror("SO_OOBINLINE ERROR");
}
//設定傳送緩衝區與接收緩衝區的大小SO_RCVBUF與SO_SNDBUF,將傳送緩衝區的大小設定為8192位元組,將接收緩衝區的大小設定為16384位元組
//TCP具有流量控制的功能,不允許傳送比滑動視窗大的資料,而UDP沒有流量控制的功能,當傳送的資料比接收緩衝區多時,會丟失資料,即快的傳送者會淹沒慢的接收者
int sndsize=8192;//真實的緩衝區大小為使用者輸入的兩倍 
int rcvsize=16384;
err=setsockopt(s,SOL_SOCKET,SO_SNDBUF,&sndsize,sizeof(sndsize));
if(err){
  perror("SO_SNDBUF ERROR");
}
err=setsockopt(s,SOL_SOCKET,SO_RCVBUF,&rcvsize,sizeof(rcvsize));
if(err){
  perror("SO_RCVBUF ERROR");
}
//傳送超時時延與接收超時時延SO_RCVTIMEO,SO_SNDTIMEO預設情況下recv函式沒有接收到資料會一直阻塞的
struct timeval t;
t.tv_sec=10;//設定為10秒
t.tv_usec=100;
int len1=sizeof(t);
err=setsockopt(s,SOL_SOCKET,SO_SNDTIMEO,&t,len1);
if(err){
  perror("SO_SNDTIMEO error");
}
err=setsockopt(s,SOL_SOCKET,SO_RCVTIMEO,&t,len1);
if(err){
  perror("SO_RCVTIMEO");
}
//SO_RCVLOWAT接收快取有最小資料位元組數,讀才不會阻塞。SO_SNDLOWAT為傳送緩衝區的最小值,預設情況下都為1位元組,寫才不會阻塞
//將傳送緩衝區空閒空間的下限值設定為2048位元組,將接收緩衝區的空閒空間設定為1位元組
int rcvlowat=10;
int sndlowat=10;//傳送緩衝區的最低空閒位元組數不能設定
err=setsockopt(s,SOL_SOCKET,SO_RCVLOWAT,&rcvlowat,sizeof(rcvlowat));
if(err){
  perror("SO_RCVLOWAT ERROR");
}
err=setsockopt(s,SOL_SOCKET,SO_SNDLOWAT,&sndlowat,sizeof(sndlowat));
if(err){
  perror("SO_SNDLOWAT ERROR");
}
//SO_REUSERADDR表示允許重複使用本地埠,某些非正常退出的伺服器程式會佔用埠一段時間才釋放,這時將不使用SO_REUSERADDR將不能繫結到埠
int reuseaddr=1;//開啟埠重複使用功能
err=setsockopt(s,SOL_SOCKET,SO_REUSEADDR,&reuseaddr,sizeof(reuseaddr));
if(err){
  perror("SO_REUSEADDR ERROR");
}

//SO_BINDTODEVICE,可以將套接字與某個介面相繫結
char ifname[]="eth0";//sizeof表示空間大小為5,加\0,strlen遇到\0結束為4
err=setsockopt(s,SOL_SOCKET,SO_BINDTODEVICE,ifname,5);//陣列名可以表示地址
if(err){
  perror("SO_BINDTODEVICE ERROR");
}
//SO_PRIORITY對套接字優先權的設定,高優先權的資料被優處理,優先權範圍0-6
int priority=6;
err=setsockopt(s,SOL_SOCKET,SO_PRIORITY,&priority,sizeof(priority));
if(err){
  perror("SO_PRIORITY ERROR");

}
/**
SOL_SOCKET:對套接字級別進行操作
IPPROTO_IP:對IP層協議進行操作
IPPROTO_TCP:對TCP層協議進行操作
**/
 while(sockopts[i].valtype!=VALMAX){
   len=sizeof(optval);//getsockopt傳入時的最大長度
   err=getsockopt(s,sockopts[i].level,sockopts[i].optname,&optval,&len);//返回的值儲存在optval緩衝區中,傳出值表示返回選項值的實際長度
 //第一個引數是套接字描述符
//第二個引數是選項所在的協議層
//第三個引數是選項名稱
//第四個引數是返回值的緩衝區
//第五個引數是返回值緩衝區的長度
   display(&sockopts[i],len,err);
   i++;
}

close(s);
return 0;

}
static void display(sopts *sockopt,int len,int err){
  if(err==-1){
   printf("optname %s not support\n",sockopt->name);
   return;
}
 
switch(sockopt->valtype){
 case VALINT:
    printf("optname %s:is %d\n",sockopt->name,optval.val);//整形值
break;
case VALLINGER:
    printf("optname %s:is %d(ON/OFF),%d to linger\n",sockopt->name,optval.linger.l_onoff,optval.linger.l_linger);//linger開啟,延遲時間
break;
case VALTIMEVAL:
    printf("optname %s:default is %.06f\n",sockopt->name,((((double)optval.tv.tv_sec*1000000+(double)optval.tv.tv_usec))/(double)1000000));
break;
case VALUCHAR:
 {
    int i=0;
        
        printf("optname %s:default is",sockopt->name);
        for(i=0;i<len;i++){
        printf("%02x ",optval.str[i]);

    }
    printf("\n");
 }
break;
default:
break;
}
}

執行結果:
[[email protected] ~]# ./socket-opt
SO_SNDLOWAT ERROR: Protocol not available
optname SO_BROADCAST:is 1
optname SO_DEBUG:is 1
optname SO_DONTROUTE:is 0
optname SO_ERROR:is 0
optname SO_KEEPALIVE:is 1
optname SO_LINGER:is 1(ON/OFF),60 to linger
optname SO_OOBINLINE:is 1
optname SO_RECVBUF:is 32768
optname SO_SNDBUF:is 16384
optname SO_SNDTIMEO:is 10.001000
optname SO_RCVTIMEO:is 10.001000
optname SO_RCVLOWAT:is 10
optname SO_SNDLOWAT:is 1
optname SO_REUSERADDR:is 1
optname SO_TYPE:is 1
optname SO_BINDTODEVICE not support
optname SO_PRIORITY:is 6
optname IP_HDRINCL:is 0
optname IP_MULTICAST_TTL:is01 00 00 00

總結:

本文主要介紹了套接字選項設定的相關函式,以及套接字層(SOL_SOCKET),IP層(IPPROTO_IP)與TCPP層(IPPROTO_TCP)選項的含義,最後給出一個具體的例子來設定和得到套接字選項的值. 套接字選項的設定在廣播和多播以及原始套接字直接得到IP包等方面有著重要的應用.


相關推薦

Linux網路程式設計選項設定

轉自 http://blog.csdn.net/chenjin_zhong/article/details/7268939 1.介紹 在Linux網路程式設計中,有時需要設定地址複用,允許傳送廣播包,將主機加入某個多播組,設定傳送與接收緩衝區的大小,設定傳送與接收的超

linux網路程式設計介面)、ip、埠理解

它是網路通訊過程中端點的抽象表示,包含進行網路通訊必需的五種資訊:連線使用的協議,本地主機的IP地址,本地程序的協議埠,遠地主機的IP地址,遠地程序的協議埠。或者說,套接字,是支援TCP/IP的網路通訊的基本操作單元,可以看做是不同主機之間的程序進行雙向通訊的端點,簡單的說就是通訊的兩方的一種約定,用套接字中

Linux網路程式設計——原始程式設計

原始套接字的建立 int socket ( int family, int type, int protocol ); 引數: family:協議族 這裡寫 PF_PACKET type:  套接字類,這裡寫 SOCK_RAW protocol:協議類別,指定可以接收或傳送的資料包型別,不能寫

Linux網路程式設計——原始例項:MAC 頭部報文分析

通過《Linux網路程式設計——原始套接字程式設計》得知,我們可以通過原始套接字以及 recvfrom( ) 可以獲取鏈路層的資料包,那我們接收的鏈路層資料包到底長什麼樣的呢? MAC 頭部(有線區域網) 注意:CRC、PAD 在組包時可以忽略 鏈路層資料包的其中一

Linux 網路程式設計——原始例項:MAC 地址掃描器

如果 A (192.168.1.1 )向 B (192.168.1.2 )傳送一個數據包,那麼需要的條件有 ip、port、使用的協議(TCP/UDP)之外還需要 MAC 地址,因為在乙太網資料包中 MAC 地址是必須要有的。那麼怎樣才能知道對方的 MAC 地址?答案是:它通

Linux 網路程式設計——原始例項:傳送 UDP 資料包

乙太網(Ethernet)報文格式(MAC頭部報文格式): IP 報文格式: UDP 報文格式: 校驗和函式: /******************************************************* 功能:     

Linux網路程式設計 tcp程式碼

本次介紹一下TCP協議下的套接字程式碼,總體來看,tcp協議比udp協議更加安全可靠,無論是從使用者使用的角度還是從編寫程式碼的角度,你會發現與udp不同的是tcp在每次通訊前,伺服器端和客戶端都會進行一次連線,連線成功後,才可以進行相互間的通訊。 套接字

網路程式設計——原始實現原理

目錄 1. 基礎知識  1.1、概述 1.2、鏈路層原始套接字  1.3、網路層原始套接字 2、原始套接字的實現 2.1  原始套接字報文收發流程 2.2鏈路層原始套接字的實現     2.2.1  套接字建

網路超時 -- 採取 SO_RCVTIMEO選項設定 ( recv / recvfrom)

  #include <sys/types.h> #include <sys/socket.h> #include <stdio.h> #include <netinet/in.h> #include <arp

網路程式設計——1. 理解網路程式設計

1.1 理解網路程式設計和套接字 網路程式設計和套接字概要 1)首先需要物理連線,如今大部分計算機都已經連線到網際網路,因此不用擔心這一點 2)資料傳輸軟體。作業系統會提供名為“套接字”的部件,套接字是網路資料傳輸用的軟體裝置。 構建接電話套接字 1)安裝電

《TCP/IP網路程式設計》第一章:理解網路程式設計 筆記

第一章:理解網路程式設計和套接字 本章程式碼,在TCP-IP-NetworkNote中可以找到。 1.1 理解網路程式設計和套接字 1.1.1構建打電話套接字 以電話機打電話的方式來理解套接字。 呼叫 socket 函式(安裝電話機)時進行的對話: 問:接

Windows Socket 網路程式設計(二) —— 程式設計原理

 一、客戶機/伺服器模式在TCP/IP網路中兩個程序間的相互作用的主機模式是客戶機/伺服器模式(Client/Server model)。該模式的建立基於以下兩點:1、非對等作用;2、通訊完全是非同步的。客戶機/伺服器模式在操作過程中採取的是主動請示方式:首先伺服器方要先啟動

python 網路程式設計 TCP例項

一. 伺服器端程式碼tcpServer.py: from socket import * from time import ctime #HOST變數為空,表示bind()函式可以繫結在所有有效的地址上 HOST = '' PORT = 21234 #設定緩衝大小為1

網路程式設計二(Socket、客戶端和服務端通訊問題)

在客戶機/伺服器工作模式中,在Server端,要準備接受多個Client端計算機的通訊。為此,除用IP地址標識Internet上的計算機之外,另還引入埠號,用埠號標識正在Server端後臺服務的執行緒。埠號與IP地址的組合稱為網路套接字(socket)。 Java語言在

網路程式設計——Socket()

網路程式設計     網路程式設計的目的就是指直接或間接地通過網路協議與其他計算機進行通訊。網路程式設計中 有兩個主要的問題,一個是如何準確的定位網路上一臺或多臺主機,另一個就是找到主機後 如何可靠高效的進行資料傳輸。在TCP/IP協議中IP層主要負責網路

python網路程式設計、HTTP協議

網路程式設計  網路目的 : 資料的傳輸 網路資料傳輸是一個複雜的過程 OSI 七層模型 --》 網路通訊標準化流程 應用層 : 提供使用者服務,具體內容由特定程式規定 表示層 : 資料的壓縮優化  會話層 : 建立應用連線,選擇傳輸層服務

Linux網路程式設計原始-ping協議實現

1.概述 PING協議是用來檢驗本地主機與遠端主機是否連線,傳送的是ICMP ECHO_REQUEST包。普通的套接字是基於TCP或者是UDP的,無法傳送ICMP包,所以必須用原始套接字來實現。PING協議的客戶端型別值為8,程式碼值為0,表示請求。而PING協議的響應端型別值為0,程式碼值也為

Linux 網路程式設計原始

1. 介紹 前面主要介紹了流式套接字(SOCK_STREAM),資料報套接字(SOCK_DGRAM),基本上能夠滿足TCP與UDP的應用。但一些問題,我們仍然無法解決,如: (1)傳送一個自定義的IP包 (2)傳送ICMP包 (3)偵聽網路上的資料包 (4)偽裝IP地址 (5

linux網路程式設計socket(十六):通過UNIX域傳遞描述符和 sendmsg/recvmsg 函式

void send_fd(int sock_fd, int send_fd) {     int ret;     struct msghdr msg;     struct cmsghdr *p_cmsg;     struct iovec vec;     char cmsgbuf[CMSG_SPACE(

網路程式設計中time_wait的作用和選項SO_REUSEADDR

這兩天看APUE為一個簡單的問題特別惱火,該問題起源於兩個套接字選項就是SO_REUSEADDR和SO_REUSEPORT其實在看的過程中問學長了,學長解釋的也比較清楚,就是自己悟性不好,一時半會沒理解。自己在網上找了幾篇優秀的部落格看了,受益頗多! 先從套接字選項SO_REUSEADD