TCP端口复用 用于TCP穿透之中。
为了验证真实性,写了一个小例子。
试验了一个端口是否可以同时进行监听接收和发送 ,创建了四个进程。
原理:
1.设置::setsockopt(accept_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof (opt));
2. ::setsockopt(accept_fd, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof (opt)); 这个设置可有可无
3.9997端口 同时绑定一个ip的两个socket,进行:一个listen,一个connect 9995
4.9995 listen,9996 connect9997
5.结果:9997 这个端口同时进行listen 和 connect。
注意:
操作系统如何区分一个socket的呢?
那就是:发送方IP、发送方Port、接收方IP、接收方Port、通信协议(Tcp/Udp),这也被称为五元素。
由这五个元素,我们就能知道为什么Tcp服务端的socket的端口号都相同而且能准确收发数据。
举个列子,如果在一个客端端程序中创建两个socket,如下表所示。
SOCKET 本方IP 本方Port 目的IP 目的Port 协议
sokcet1 127.0.0.1 8000 192.168.1.1 9000 Tcp
socket2 127.0.0.1 8000 192.168.1.1 10000
Tcp
因为目的Port不一致,所以操作系统能够区分两个socket,所以两个socket均能正常通信。
但是如果这五个元素都一直,则采用Tcp协议进行connect时,就会出现连接错误,因为五元素出现了重复,操作系统不能区别两个socket。
也就是说,只要五元素不完全一致,操作系统就能区分socket。
进行收发的时候,双方都会各自创建两个socket,一个用于收一个用于发,这就会导致,通信时候,五元素会重复。所以,
一个端口接收的地址和 其发送的端口,目标地址不能相同。
问题: 9998 -》9996 listen的socket 和 9998 -》9996 connect的socket 相同 。所以这个理论有待考究。
但是TCP通信是双向的 两个socket建立连接之后 便不再去管listen或connect。
代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include<netinet/in.h>
#include<sys/socket.h>
#include<time.h>
#include<cs