1,用戶端和伺服器通信時,資料如果沒有進行互動,我們怎麼去定位問題,
首先tcpdump抓包,如果找到封包資料,說明通信正常,如果沒有抓到封包資料,那接下來怎麼去看呢
封包發送方和接收方端口确認
(1)netstat的使用:
[[email protected]:/root]# netstat -a
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 (null):ssh (null):* LISTEN
tcp 0 0 (null):6560 (null):* LISTEN
tcp 0 0 (null):2023 (null):* LISTEN
tcp 0 0 (null):53000 (null):* LISTEN
tcp 0 320 (null):ssh (null):63900 ESTABLISHED
tcp 0 0 :::ssh :::* LISTEN
udp 0 0 (null):6300 (null):*
udp 0 0 (null):6301 (null):*
LISTEN:表示已經被占用,後面的PID/Program name 可以看到程序名稱
ESTABLISHED:是對方與你已經産生了連接配接 正在通信交換資料
(2)netstat -nultp
[[email protected]:/root]# netstat -nultp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 2008/sshd_config [l
tcp 0 0 0.0.0.0:6560 0.0.0.0:* LISTEN 2061/stswitch
tcp 0 0 0.0.0.0:2023 0.0.0.0:* LISTEN 2060/netserve
tcp 0 0 127.0.0.1:53000 0.0.0.0:* LISTEN 2061/stswitch
tcp 0 0 :::22 :::* LISTEN 2008/sshd_config [l
udp 0 0 0.0.0.0:6300 0.0.0.0:* 2061/stswitch
udp 0 0 0.0.0.0:6301 0.0.0.0:* 2061/stswitch
(3)udp通信端口
[[email protected]:/root]# netstat -nulp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
udp 0 0 0.0.0.0:6300 0.0.0.0:* 2061/stswitch
udp 0 0 0.0.0.0:6301 0.0.0.0:* 2061/stswitch
netstat -nua(檢視udp連接配接,注意看第二列和第三列 ,檢視ip和端口資訊)
注意:udp沒有建立連接配接的過程,是以這裡不用看最後的狀态。
[[email protected]:/app]# netstat -nua
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
udp 0 0 0.0.0.0:50067 0.0.0.0:*
udp 0 0 126.0.1.9:9 0.0.0.0:*
udp 0 0 126.0.1.9:69 0.0.0.0:*
udp 0 0 0.0.0.0:6300 0.0.0.0:*
udp 0 0 0.0.0.0:6301 0.0.0.0:*
udp 0 0 0.0.0.0:6302 0.0.0.0:*
udp 1664 0 126.0.1.9:40587 0.0.0.0:*
(4)tcp通信端口
[[email protected]:/root]# netstat -nltp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 2008/sshd_config [l
tcp 0 0 0.0.0.0:6560 0.0.0.0:* LISTEN 2061/stswitch
tcp 0 0 0.0.0.0:2023 0.0.0.0:* LISTEN 2060/netserve
tcp 0 0 127.0.0.1:53000 0.0.0.0:* LISTEN 2061/stswitch
tcp 0 0 :::22 :::* LISTEN 2008/sshd_config [l
[[email protected]:/app]# netstat -nt
Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 127.0.0.1:8002 127.0.0.1:48232 ESTABLISHED
tcp 0 0 172.17.2.221:22 172.17.1.26:64017 ESTABLISHED
tcp 0 304 172.17.2.221:22 172.17.1.26:63900 ESTABLISHED
tcp 0 0 127.0.0.1:48232 127.0.0.1:8002 ESTABLISHED
(5)在互相通信的另一端也可以檢視端口資訊,檢視端口是否建立,端口是否被占用。
2,函數端口屬性,以udp舉例說明:
int socket_fd = 0;
int ret = 0;
struct sockaddr_in sock_addr = {0};
/* 1. create udp socket */
socket_fd = socket(AF_INET, SOCK_DGRAM, 0);
if(socket_fd < 0) {
ST_DAL_LOG_ERROR("create udp socket fail");
return -1;
}
/* 2. set socket option */
reuse = reuse & 0x01;
setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
setsockopt(socket_fd, SOL_SOCKET, SO_REUSEPORT, &reuse, sizeof(reuse));
broadcast = broadcast & 0x01;
setsockopt(socket_fd, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof(broadcast));
if (if_name)
{
setsockopt(socket_fd, SOL_SOCKET, SO_BINDTODEVICE, if_name, sizeof(struct ifreq));
}
/* 3. bind udp socket */
sock_addr.sin_family = AF_INET;
sock_addr.sin_addr.s_addr = htonl(addr);
sock_addr.sin_port = htons(port);
if (bind(socket_fd, (struct sockaddr *)&sock_addr, sizeof(sock_addr)) < 0)
{
ST_DAL_LOG_ERROR("bind udp socket fail, addr %08x port %d", addr, port);
return -1;
}
(1)SO_REUSEADDR使用說明:
a,允許啟動一個監聽伺服器并捆綁其衆所周知端口,即使以前建立的将此端口用做他們的本地端口的連接配接仍存在。這通常是重新開機監聽伺服器時出現,若不設定此選項,則bind時将出錯
b,允許在同一端口上啟動同一伺服器的多個執行個體,隻要每個執行個體捆綁一個不同的本地IP位址即可。對于TCP,我們根本不可能啟動捆綁相同IP位址和相同端口号的多個伺服器。
c,允許單個程序捆綁同一端口到多個套接口上,隻要每個捆綁指定不同的本地IP位址即可。這一般不用于TCP伺服器。
d, 允許完全重複的捆綁:當一個IP位址和端口綁定到某個套接口上時,還允許此IP位址和端口捆綁到另一個套接口上。一般來說,這個特性僅在支援多點傳播的系統上才有,而且隻對UDP套接口而言(TCP不支援多點傳播)
補充:一個端口釋放後會等待兩分鐘之後才能再被使用,SO_REUSEADDR設定後,端口釋放後立即就可以被再次使用。
(2) SO_REUSEPORT
SO_REUSEPORT支援多個程序或者線程綁定到同一端口,提高伺服器程式的性能,解決的問題:
- 允許多個套接字 bind()/listen() 同一個TCP/UDP端口
- 每一個線程擁有自己的伺服器套接字
- 在伺服器套接字上沒有了鎖的競争
- 核心層面實作負載均衡
- 安全層面,監聽同一個端口的套接字隻能位于同一個使用者下面
可以重複綁定端口,函數不會報錯。
(3)SO_BINDTODEVICE
使用指定網卡,例如eth0,eth1,eth2等等。
(4)SO_BROADCAST
打開該屬性後,一般在發送UDP資料報的時候,該socket發送的資料具有廣播特性。