socket端口复用问题、接收缓冲区、发送缓冲区-- SetSockOpt

默认情况下,一个网络应用程序的一个socket绑定了一个端口,这时候其他socket就无法使用这个端口了。

端口复用

端口复用允许在一个应用程序中把多个socket绑定在一个端口上。

设置socket的SO_REUSEADDR选项,即可实现端口复用。

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

sockfd:标识一个套接口的描述字。
level:选项定义的层次;支持SOL_SOCKET、IPPROTO_TCP、IPPROTO_IP和IPPROTO_IPV6。
optname:需设置的选项。
optval:指针,指向存放选项待设置的新值的缓冲区。
optlen:optval缓冲区长度。

setsockopt()支持下列选项。其中“类型”表明optval所指数据的类型。(部分)

选项 类型 意义
SO_REUSEADDR BOOL 允许套接口和一个已在使用中的地址捆绑(参见bind())
SO_SNDBUF int 指定发送缓冲区大小
SO_RCVBUF int 接收确定缓冲区大小

端口复用:

bool opt = true;
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (const void *)&opt, sizeof(opt));

SO_REUSEADDR可以用在以下四种情况下。 (摘自《Unix网络编程》卷一,即UNPv1)

1、当有一个有相同本地地址和端口的socket1处于TIME_WAIT状态时,而你启动的程序的socket2要占用该地址和端口,你的程序就要用到该选项。

2、SO_REUSEADDR允许同一port上启动同一服务器的多个实例(多个进程)。但每个实例绑定的IP地址是不能相同的。在有多块网卡或用IP Alias技术的机器可以测试这种情况。

3、SO_REUSEADDR允许单个进程绑定相同的端口到多个socket上,但每个socket绑定的ip地址不同。这和2很相似,区别请看UNPv1。

4、SO_REUSEADDR允许完全相同的地址和端口的重复绑定。但这只用于UDP的多播,不用于TCP。

需要注意的是,设置端口复用函数要在绑定之前调用,而且只要绑定到同一个端口的所有套接字都得设置复用:

接收缓冲区和发送缓冲区

每个Socket都有自己的Send Buffer和Receive Buffer。
当进行send和recv操作时,立即返回,其实是将数据并没有发送出去,而是存放在对应的Send Buffer和Receive Buffer马上返回成功。.

TCP的全双工的工作模式以及TCP的滑动窗口便是依赖于这两个独立的buffer以及此buffer的填充状态。

接收缓冲区 RCVBUF
	接收缓冲区把数据缓存入内核,应用进程一直没有调用read进行读取的话,此数据会一直缓存在相应socket的接收缓冲区内。
	(不管进程是否读取socket,对端发来的数据都会经由内核接收并且缓存到socket的内核接收缓冲区之中。)
	read所做的工作,就是把内核缓冲区中的数据拷贝到应用层用户的buffer里面,仅此而已。

接收缓冲区buffer满了以后

接收缓冲区被TCP和UDP用来缓存网络上来的数据,一直保存到应用进程读走为止。

**TCP可靠而UDP不可靠的实现**
·TCP
	对于TCP,如果应用进程一直没有读取,buffer满了之后,发生的动作是:通知对端TCP协议中的窗口关闭。这个便是滑动窗口的实现。
	保证TCP套接口接收缓冲区不会溢出,从而保证了TCP是可靠传输。因为对方不允许发出超过所通告窗口大小的数据。 这就是TCP的流量控制,如果对方无视窗口大小而发出了超过窗口大小的数据,则接收方TCP将丢弃它。
·UDP
	当套接口接收缓冲区满时,新来的数据报无法进入接收缓冲区,此数据报就被丢弃。UDP是没有流量控制的;快的发送者可以很容易地就淹没慢的接收者,导致接收方的UDP丢弃数据报。
发送缓冲区 SNDBUF
	进程调用send发送的数据的时候,最简单情况(也是一般情况),将数据拷贝进入socket的内核发送缓冲区之中,然后send便会在上层返回。
	换句话说,send返回之时,数据不一定会发送到对端去(和write写文件有点类似),send仅仅是把应用层buffer的数据拷贝进socket的内核发送buffer中。
	每个UDP socket都有一个接收缓冲区,没有发送缓冲区,从概念上来说就是只要有数据就发,不管对方是否可以正确接收,所以不缓冲,不需要发送缓冲区。

端口复用参考:
https://www.cnblogs.com/wangshaowei/p/10557539.html
发送接收缓冲区参考:
http://blog.chinaunix.net/uid-29075379-id-3905006.html
https://www.jianshu.com/p/755da54807cd

你可能感兴趣的:(计算机网络)