socket系列之socket服务端与客户端如何通信-阿里云开发者社区

开发者社区> sea-boat> 正文

socket系列之socket服务端与客户端如何通信

简介: 上面已经分别介绍了ServerSocket跟Socket的工作步骤,并且从应用层往系统底层剖析其运作原理,我们清楚了他们各自的一块,现在我们将把他们结合起来,看看他们是如何通信的,并详细讨论一下他们之间相互通信的一些细节。
+关注继续查看
上面已经分别介绍了ServerSocket跟Socket的工作步骤,并且从应用层往系统底层剖析其运作原理,我们清楚了他们各自的一块,现在我们将把他们结合起来,看看他们是如何通信的,并详细讨论一下他们之间相互通信的一些细节。
借助图2-3-2-4,想象一下你正在大学课室上着电脑,你跟你另外两个朋友觉得老师讲得课很菜,没必要听,于是你们仨都各自打开浏览器冲浪,刚好你们访问了同一台服务器,假如你用的是浏览器A,那么整个流程为:
浏览器确认目标IP跟目标端口号(http默认使用80端口),当然如果你在浏览器地址栏输入带端口的地址,那么目标端口号将是你指定的端口,另外浏览器还将组织http报文,一并将这些参数传入系统底层socket。
系统层socket对TCP/IP协议的操作,从前面我们已经学到,一层一层往下其实就是将报文一层一层包起来,所以这里是先用http报文组织成TCP报文,再组织成IP报文,其中socket的源端口是随机分配的(一个大于1023随机数),最后放到TCP/IP栈里,排队发送消息。
ServerSocket正在堵塞监听接收连接,客户端socket与之建立连接。
服务器端根据客户端请求创建socket,此socket即可用于跟客户端socket进行通信。
服务器处理相关逻辑,例如数据库操作,逻辑判断等等。
服务器处理完,行成相应的用于客户端浏览器显示的http报文,http报文经过tcp跟ip协议包装,返回给客户端socket。
客户端经过层层解析,把http报文传到浏览器,浏览器对http报文进行解析,最后一个漂亮整洁的网页展示在你眼前。
释放关闭连接。
如果你们仨在同一时间访问,服务器为了能有更好地性能,为了几乎同一时间响应你们,而不是一个处理完才处理另外一个,服务器会采取多线程处理,一个线程处理一个请求。
 
图2-3-2-4 ServerSocket与Socket通信模型


上面的通信模型从较宏观的层面描述了socket之间的通信,而在通信过程中必然涉及数据报文的传输,接着将学习socket底层数据的传输模型。图2-3-2-5形象地展现了数据是怎样从应用层到系统底层,再到互联网传输的。首先先介绍两个FIFO队列:SendQ跟RecvQ。它们都处于系统底层,在传输过程中充当缓冲区的作用,SendQ是把应用层发送到系统底层的数据进行缓冲,然后排队发送到因特网的队列,而RecvQ则是把从因特网接收到的数据进行缓冲,等待应用层去读取的队列。具体步骤如下:
应用层的Socket或Serversocket把要发送的数据写入系统底层的SendQ队列。
SendQ队列根据先进先出原则,把这些数据发往因特网,到达目标主机。(从传输层来看,可以认为这时的数据是TCP报文)
如果有数据从因特网发送过来,首先会被接收到RecvQ队列进行缓冲。
应用层的Socket或Serversocket会循环尝试读取RecvQ队列,如果有数据则读取到应用层。
从中可以总结,TCP协议其实就是负责将数据按顺序从SendQ与RecvQ之间互相转移。而且从我们应用层来看这个转移过程我们是没有办法控制或直接观察的。同时,由于TCP提供可靠的数据传输服务,所以任何写入SendQ队列的数据都必须要保留一份数据副本,直到连接的另外一端成功接收。另外,Socket通过输出流向SendQ写数据并不意味着数据已经被发送,他们仅仅只是到了缓冲区,就算Socket的输出流进行了flush()操作也不能保证数据马上被发送到信道。
 
图2-3-2-5 socket数据传输模型


那么我们能不能就认为在连接的一端写入数据,另外一端就能马上读取数据呢?接着我们将更深入探讨SendQ与RecvQ队列里面的数据是怎样传输的,这个过程应该说是以块来传输的,而这些块的大小在一定程度上独立于应用层socket读写的缓冲大小。
如图2-3-2-6,假如应用层socket调用输出流write()方法向SendQ队列写数据,三次写入的数据大小分别为1000字节、2000字节、5000字节,而假设SendQ队列的缓存块大小为3000字节,第一次1000字节加上2000字节刚好等于3000字节,那么这两次的数据作为一个块进行传输。通过因特网到达RecvQ队列,应用层socket再通过输入流的read()方法读取RecvQ里的数据,输入流缓冲区读取了RecvQ队列3000字节就返回值3000。
 
图2-3-2-6 socket底层的块传输


在现实使用中,SendQ跟RecvQ队列可能会被无限填充, 为了防止一个TCP连接将系统内存全部耗尽,必须要对SendQ跟RecvQ队列的大小进行限制。一旦RecvQ队列数达到最大值,TCP流控制就会通知SendQ先停止发送数据,等我的RecvQ中的数据被socket输入流读走了有空间了再传给我。这样就能有效地控制过量发送,有效杜绝超出系统接收处理能力的情况。对于socket输出流可以不断写入数据,直到SendQ队列被填满了,此时write()方法将会阻塞等待。


==========广告时间==========

鄙人的新书《Tomcat内核设计剖析》已经在京东预售了,有需要的朋友可以到 https://item.jd.com/12185360.html 进行预定。感谢各位朋友。

=========================



版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
Java Socket服务端客户端通信实例
本文目录 1. Socket是啥 2. 运行机制 3. 代码示例 4. 测试 5. 小结
13 0
【.Net MF网络开发板研究-04】Socket编程之服务端
    .NET Micro Framework的Socket函数和桌面版.NET Framework中的函数完全兼容,换句话说,就是用.NET Micro Framework编写的Socket程序直接用桌面版的.NET Framework进行编译运行是完全没有问题的。
545 0
我的mqtt协议和emqttd开源项目个人理解(23) - websocket客户端连接过程分析(Wireshark抓包+源码分析)
我的mqtt协议和emqttd开源项目个人理解(23) - websocket客户端连接过程分析(Wireshark抓包+源码分析)
35 0
C# 实现客户端Socket断开后重新连接。
C# 实现客户端Socket断开后重新连接。
25 0
【.Net MF网络开发板研究-05】Socket编程之客户端
官方示例中也包括了SocketClient,不过其完成的功能一是DNS解析,二是网站数据接收。我们需要大幅度改进一下,让SocketClient程序和PC上的Socket Server进行通信。
423 0
在IIS上搭建WebSocket服务器(二)
原文:在IIS上搭建WebSocket服务器(二) 服务器端代码编写 1.新建一个ASP.net Web MVC5项目   2.新建一个“一般处理程序” 3.Handler1.ashx代码如下: using System; using System.
2038 0
在IIS上搭建WebSocket服务器(三)
原文:在IIS上搭建WebSocket服务器(三) 编写客户端代码 1.新建一个*.html文件。 ws = new WebSocket('ws://192.168.85.128:8086/Handler1.
1551 0
+关注
sea-boat
擅长篮球、跑步、游泳、羽毛球、编程、看书、写书的顾家好男人! Java深度、大数据、中间件、搜索引擎、机器学习、深度学习、Python、C++、开源! 《Tomcat内核设计剖析》作者。
276
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
《Nacos架构&原理》
立即下载
《看见新力量:二》电子书
立即下载
云上自动化运维(CloudOps)白皮书
立即下载