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发送的数据具有广播特性。