简书上的大牛总结的 ServerSocket Accept() 的确是阻塞方法 与猜想一致 一些理解 转载如下

 

当我们调用如下代码的时候,实际java封装了很多层调用

 

图1

new ServerSocket(9876) 这个构造函数的内部,会调用 bind() 以及 listen() 等系统调用,之后才是 accept(),下面依次讲解。

bind(): bind 只是简单的将套接字和 地址端口联系上,调用bind()之后,netstat 不会看到任何连接

listen(): listen 表示此套接字 已经处于监听状态了,外部请求可以打进来了。

 

 

图2

 

可以看到,并没有运行到 accept() ,socket已经处于监听状态了,那此时如果外部连接打进来会怎样呢?我们用浏览器模拟http请求。 打开 chrome 输入 127.0.0.1:9876 回车,

 

图3

可以看到 55870 端口建立了连接 (ESTABLISHED 表示连接已经建立)  (55868那个端口不知道怎么来的,有知道的大神希望能指点一下)。然后我们在浏览器多开几个窗口输入,会发现连接建立的更多了。

 

图4

所以,listen的时候,是可以接收请求并建立连接的,只是不处理这个socket的内容而已。参考UNIX网络编程(卷一,套接字联网API 第三版 p85),此时系统维护两个队列,未完成建立连接队列(三次握手只进行了第一步)和 已完成建立连接队列(上述ESTABLISTHED的连接)。而之后的 accept() 会在已建立连接队列获取套接字来处理。

accept() :会从上述已建立连接套接字队列,获取队列头部的socket,来进行处理,每次accept()都会返回一个对应客户端的全新socket 。当建立连接队列为空时,accept会阻塞并处于睡眠状态。

另注:当accept() 之后,如果一个请求打过来,服务器处理请求之后,并不会将连接中断,而是会一直通过 客户端的 keepAlived 来维持这个连接

 

图4

可以看到  都是从客户端发送的 keepalived 请求,服务端回应ack。

补充一下:在listen之前,创建的socket都默认为要主动 connect 其他服务的,即为主动socket,只有listen 之后,socket 才变为被动的。服务端的socket 都是listen了之后,才变为服务socket的。



作者:熊哥的世界
链接:https://www.jianshu.com/p/64ca562f156a
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

 

https://www.jianshu.com/p/64ca562f156a

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值