//設定socket屬性
int getsockopt(intsockfd, int level, int optname,void *optval, socklen_t *optlen);
int setsockopt(intsockfd, int level, int optname,const void *optval, socklen_t optlen);
功能:獲得或是設定socket屬性
引數:@sockfd 要設定的socket
@level socket 層次
sol_socket //通用的socket選項
ipproto_ip //ip層
ipproto_tcp //tcp層
@optname
選項@optval 選項對應的一些具體值
@optlen optval值的大小
返回值:
成功 0
失敗 -1 &errno
//接收超時的設定
//1.設定超時時間
struct timeval tm = ;
if(setsockopt(sockfd,sol_socket,so_rcvtimeo,&tm,sizeof(tm)) < 0)
perror("setsockopt fail");
exit(exit_failure);
//設定ip+port 復用--- 開啟某些選項的功能
int on = 1; //大於0 的值表示開啟這項功能
if(setsockopt(sockfd,sol_socket,so_reuseaddr,&on,sizeof(int)) < 0)
perror("setsockopt fail");
exit(exit_failure);
linux
所提供的socket庫中存在乙個bug,即不能為乙個套接字重新啟用同乙個埠,即使是你正常關閉該套接字以後,這是因為linux核心在乙個繫結套接字的程序結束後從不把埠標記為未用。為了解決上述問題,setsockopt和getsockopt函式就被引進來了,當然它倆的功能不止這一點。
函式原型:
1.
int setsockopt(
int sockfd,
int level,
int optname,const void *optval,
socklen_t
*optlen)
2.
intgetsockopt
(int
sockfd
,int
level
,int
optname
,const void
*opt
val,
socklen_t
*optlen)
其中level
是函式所使用的協議標準,可以取如下值:
1. sol_socket: 基本套介面
2.
ipproto_ip
:ipv4
套介面
3.
ipproto_ipv6
:ipv6
套介面
4.
ipproto_tcp
:tcp
套介面
optval
是指向setsockopt函式所設定的值的位址,getsockopt函式所獲取的值
optlen
是optval的長度,以bytes計
optname
是選項的名稱,可以取如下值:
1. so_broadcast bool型別 允許套介面傳送廣播資訊
2.
so_debug bool
型別記錄除錯資訊
3.
so_dontliner bool
型別不要因為資料未傳送就阻塞關閉操作
4.
so_dontroute bool
型別禁止選擇徑;直接傳送
5.
so_keepalive bool
型別傳送保持活動包
6.
so_linger struct linger far
*如關閉時有未傳送資料,則逗留
7.
so_oobinline bool
型別在常規資料流中接收帶外
(out-of-band)資料
8.
so_rcvbuf
int型別
為接收確定緩衝區大小
9.
so_reuseaddr bool
型別允許套介面和乙個已在使用中的位址**
10.
so_sndbuf
int型別
指定傳送緩衝區大小
埠可重用的**片斷
1. s = socket(...)
2.
bool isreusable
=true;
3.
setsockopt(s
,sol_socket
,so_reuseaddr
,(const
char
*)&isreusable
,sizeof
(bool
));
//檢測客戶端是否存活
tcp:(核心協議棧實現的)
keepalive
udp:(心跳包的機制)
客戶端: 定時傳送乙個資料報 (alarm --- 訊號 --- 訊號處理函式(send,重啟定時))
伺服器端:
設定超時等待, 如果在指定的超時時間內,沒有獲得客戶端的資訊,則認為超時
注意:對於客戶端的探測,我們通常放到應用層中去做
udp 實現可靠傳輸:(相互的確認機制)
思路:每個包新增乙個序號
進行確認機制的新增
c------s
100-->
<--101-
---102-> s
tcp:三次握手
c ----------- s
-----syn(j)------>
<-ack(j+1),syn(k)--
-----ack(k+1)---->
1.廣播
單播多播(組播)
廣播廣播:
傳送方--- 電台
1.建立套接字 socket() //sock_dgram
2.開啟廣播屬性 setsockopt
3.填充廣播位址資訊 struct sockaddr_in
4.往廣播位址中發訊息 sendto
接收方:----- 收音機
1.建立套接字
2.填充廣播位址
3.繫結廣播位址 ---- 調頻 bind
4.接收廣播 recvfrom
多播:d類位址
224.0.0.1 ---- 239.255.255.255
流程:傳送方:
[1].socket
[2].填充多播位址
[3].往多播位址中傳送資料
接收方:
[1].socket
[2].加入多播組
[3].繫結多播位址 --- 類似調頻
[4].接收資料
struct ip_mreq
struct in_addr imr_multiaddr; //指定的要加入的多播位址
struct in_addr imr_inte***ce; //指定從那張網絡卡接收資料
//1.定義多播請求的結構體變數進行填充
struct ip_mreqmreq;
bzero(&mreq,sizeof(mreq));
mreq.imr_imr_multiaddr.s_addr= inet_addr(「224.10.10.1」);//填充多播位址
mreq.imr_imr_inte***ce.s_addr= htonl(inaddr_any); //填充接收的網絡卡位址
//2.加入到多播組
setsockopt(sockfd,ipproto_ip, ip_add_membership, &mreq,sizeof(mreq)); //加入多播組
//ipproto_ip --- ip
//ip_add_membership加入到多播組
設定socket的屬性
之前一直沒明白setsockopt的作用。原來是用來設定socket的屬性。setsockopt設定so reuseaddr。socket關閉之後並不會立即收回,而是要經歷乙個time wait的階段。windows下最多可以達到4分鐘。所以在這個時候對這個埠進行重新繫結就會出錯。所以需要先設定 s...
服務端socket重用屬性設定
socket是一種系統資源,並不是每次初始化都一定成功,因此為了避免初始化失敗,一般使用多次初始化的方式,如下所示 unsigned int times 0x0 while server socket pf inet6,sock stream,0 0 times 0x3 一般來說,乙個埠釋放後需要等...
Socket屬性總結
socket有許多的控制選項,總結如下 1 tcp nodelay 表示立即傳送資料 2 so resuseaddr表示是否立即重用socket所繫結的本地位址 3 so linger表示當執行socket的close 方法時,是否立即關閉底層的socket 4 so snfbuf表示傳送資料的緩衝...