socket是把计算机互相连接起来的

来源:7-1 NIO编程模型精讲

WittChen

2021-07-21

问题描述
老师您好,我有个钻牛角尖的问题,计算机是怎么确定连接状态的,比如客户端与服务端连接了,服务端有一个readLine的阻塞的方法,当客户端发送消息,服务端可以接收到,但如果客户端因为意外

**问题一:**比如停电,机器突然停止了,服务端可以立马知道客户端已经关闭了连接,那服务端是怎么知道的呢
**自问自答:**那这两台机器在连接的状态下是不是都会有一定频率的进行交流,而保证当时是连接状态,一旦一方停止交流或者网络阻塞,那么另一方就能立马知道
**问题二:**我们使用Java程序进行socket连接时,readLine又是通过什么技术能时时读到客户端的内容的呢

自问自答:readLine是输入流的方法,那么既然已经连接了,输入流应该是时时监听着网络,就像从文件输入一样,现在数据源换成了网络而已,一旦数据源中有内容,那么我就读取内容到输入流当中,输入流中一旦有数据了,我就返回数据,这个readLine的方法有点像之前老师讲过的Callable,必须有返回值的线程,目前我只能脑补到这里

文字有点多,可能讲得也很乱,多包涵

写回答

1回答

逐梦稚者

2022-02-02

我在看B站的中科大郑铨老师的计算机网络以前,也有相同的问题,看完那套课以后,感觉大概懂了一些,来尝试回答一下这几个问题。

首先,需要理解Socket是什么东西。

可以把Socket理解为一个内核层的对象,它保存了自己的ip和端口,保存了它连接的服务器的ip和端口,保存了创建自己这个Socket对象的进程号。内核层保存了List<Socket>的列表。

当网络数据通过网卡到达内核然后按照分层从下向上解析,能够得到本次数据是发送给哪个ip和端口,内核从它的列表中找到Socket对象,从中取出进程号,再把数据转发给对应的进程。

这就是你的Q2,readLine()时,网卡中没有数据给到它,它就阻塞在那里。当有数据到达时,内核会把数据交给对应的进程。

其实,需要理解Socket是怎样发送数据的。

应用层,就比如QQ微信要发送一条消息,它把String转换成byte[],然后交给Socket。Socket保存了服务器的ip和端口,内核就可以把数据和ip/port向下层逐层封装,交给路由器和网线。在这过程中,假如网络正常,它就会根据路由表一跳一跳得找到服务器,把数据送过去。中间的路可能不通,发送方就可以会重新发送,重试次数超过限定,就会失败。

这就是你的Q1,对服务器也一样,Socket本身只是内核内存中的一个对象。Socket不会实时感知对方。只有对方正常发出结束连接的消息,Socket才会正常从内存中移出。

有个东西叫做心跳,它就是为了避免服务器想推送消息时,发现客户端Socket已经失效了,客户端需要定时发送心跳,证明自己还有效。

突然关机,服务器发送客户端离线,就是因为服务器收不到客户端的心跳,服务器认为此连接不通,也就不用再维护这个内存对象。

1
0

系统学习Java网络编程 深度理解BIO/NIO/AIO

对比式学习助你真正理解BIO/NIO/AIO三大网络编程模型。

880 学习 · 148 问题

查看课程