Socket之bind、listen实现

Socket之bind、listen实现,第1张

bind()函数的使用方法很简单,但是它是怎么实现的呢?
本文将从应用层出发,沿着网络协议栈,分析了bind()、 listen()的系统调用、Socket层实现,以及它的TCP层实现。

应用层

int bind(int sockfd, const struct sockaddr my_addr, socklen_t addrlen);

bind() gives the socket sockfd the local address my_addr

给socket描述符绑定IP和端口,一般服务器才需要。端口号的范围为0 ~ 65535。调用bind()时,一般不要把端口号置为小于1024的值,因为1到1023是保留端口号。

系统调用

bind()是由glibc提供的,声明位于include/sys/socketh中,实现位于sysdeps/mach/hurd/bindc中,主要是用来从用户空间进入名为sys_socketcall的系统调用,并传递参数。sys_scoketcall()实际上是所有socket函数进入内核空间的共同入口。
在sys_socketcall()中会调用sys_bind()。

经过了socket层的总入口sys_socketcall(),现在进入sys_bind()。

经过了socket层的总入口sys_socketcall(),现在进入sys_bind()。

通过文件描述符,找到对应的file结构。

通过file结构,找到对应的socket结构。

把用户空间的socket地址复制到内核空间,同时检查是否合法,成功返回0。

socket层

SOCK_STREAM套接口的socket层 *** 作函数集实例为inet_stream_ops,其中绑定函数为inet_bind()。

socket层做的主要事情为合法性检查、绑定IP地址,而真正的端口绑定是在TCP层进行的。

应用层
int listen(int sockfd, int backlog);
Accept incoming connections and a queue limit for incoming connections

backlog的定义

Now it specifies the queue length for completely established sockets waiting to be accepted,

instead of the number of incomplete connection requests The maximum length of the queue

for incomplete sockets can be set using the tcp_max_syn_backlog sysctl When syncookies

are enabled there is no logical maximum length and this sysctl setting is ignored

全连接队列的最大长度:
backlog保存的是完成三次握手、等待accept的全连接,而不是半连接。
负载不高时,backlog不用太大。(For complete connections)

系统最大的、未处理的全连接数量为:min(backlog, somaxconn),netcoresomaxconn默认为128。

半连接队列的最大长度:
tcp_max_syn_backlog默认值为256。(For incomplete connections)
当使用SYN Cookie时,这个参数变为无效。

半连接队列的最大长度为backlog、somaxconn、tcp_max_syn_backlog的最小值。

listen()是由glibc提供的,声明位于include/sys/socketh中,实现位于sysdeps/mach/hurd/listenc中,主要是用来从用户空间进入名为sys_socketcall的系统调用,并传递参数。sys_socketcall()实际上是所有socket函数进入内核空间的共同入口。
在sys_socketcall()中会调用sys_listen()。

经过了socket层的总入口sys_socketcall(),现在进入sys_listen()。

SOCK_STREAM套接口的socket层 *** 作函数集实例为inet_stream_ops,其中监听函数为inet_listen()。

检查套接口的状态、当前连接的状态是否合法,然后调用inet_csk_listen_start()启动监听。

启动监听时,做的工作主要包括:

listen_sock结构用于保存SYN_RECV状态的连接请求块,所以也叫半连接队列。

(1)创建

queue是连接请求控制块,nr_table_entries是半连接的最大个数,即backlog。

(2)销毁
销毁连接请求块中的listen_sock实例,释放半连接队列。

1网络自身问题(服务器带宽不足或负载过大)。2网线问题导致网速变慢(双绞线不合规格,表现为:一种情况是刚开始使用时网速就很慢;另一种情况则是开始网速正常,但过了一段时间后,网速变慢)。3网络中存在回路导致网速变慢。4网络设备硬件故障弓|起的广播风暴而导致网速变慢。5网络中某个端口形成了瓶颈导致网速变慢。6蠕虫病毒的影响导致网速变慢。7防火墙的过多使用。8系统资源不足。还有可能是软件的问题。

默认的情况下,nginx是监听所有能到这个服务器的端口的“listen 80;”,即是说,网络能连接到的话,nginx能就能访问。
建议:
1、检查一下主机的防火墙或策略,是否把80端口禁用了。
2、如果客户端和服务器不在同一个网段,需要在路由器设置映射或者路由功能。
3、检查设置nginxconf里面,有没有deny相关的设置。
4、在服务端本地打开>1、创建一个socket套接字。
2、绑定服务器的IP和端口port。
3、开启监听listen将服务器的主动连接变成被动连接。
4、等待客服端的请求连接。
5、接收客服端的数据请求,向客服端发送数据。以上是_pro自己开服务器的方法。

nettcplisten用来监控端口是否有程序运行,比如我们网站部署到80端口,listen就可以判断是否运行
nettcpport用来监控端口是否开放,比如我们设置防火墙或者是在阿里云服务器安全组内关闭80端口就会报警

如果你是用的apache的话,你可以查看下配置文件中的Listen部分,改成Listen 80就可以监听所有网段了。如果是其他的服务器,再补充下问题吧~
嗯,还有你电脑有哪些防火墙,windows的防火墙也会让apache不能从其他机器访问~~你试试^_^


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/13477852.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-08-15
下一篇 2023-08-15

发表评论

登录后才能评论

评论列表(0条)

保存