socket系列之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()方法将会阻塞等待。
喜欢研究java的同学可以交个朋友,下面是本人的微信号:
socket系列之socket服务端与客户端如何通信的更多相关文章
- (C#:Socket)简单的服务端与客户端通信。
要求:1.可以完成一对一的通信:2.实现服务端对客户端一对多的选择发送:3.可以实现服务端的群发功能:4.可以实现客户端文件的发送: 要点:服务器端:第一步:用指定的端口号和服务器的ip建立一个End ...
- LinuxC语言实现服务端与客户端多进程通信
链接:https://pan.baidu.com/s/1YDNIyTKAkh4E5x2dBeTgcQ 提取码:y35q 复制这段内容后打开百度网盘手机App,操作更方便哦 本实验用的是Centos7m ...
- 使用WebSocket实现服务端和客户端的通信
开发中经常会有这样的使用场景.如某个用户在一个数据上做了xx操作, 与该数据相关的用户在线上的话,需要实时接收到一条信息. 这种可以使用WebSocket来实现. 另外,对于消息,可以定义一个类进行固 ...
- JAVA中Socket的用法模拟服务端和客户端
<看透springMvc源代码分析与实践>学习笔记 Socket分为ServerSocket和Socket两个大类 ServerSocket用于服务端,可以通过accept方法监听请求,监 ...
- 一: WCF的服务端与客户端在通信时有三种模式:请求响应模式、数据报模式和双工通讯模式。
说一下基本知识, 1.如果想要将当前接口作为wcf服务器,则一定要加上[ServiceContract] 契约 2.要想将方法作为wcf服务方法发布给外部调用,则一定要加上 [Operatio ...
- C# Socket服务端与客户端通信(包含大文件的断点传输)
步骤: 一.服务端的建立 1.服务端的项目建立以及页面布局 2.各功能按键的事件代码 1)传输类型说明以及全局变量 2)Socket通信服务端具体步骤: (1)建立一个Socket (2)接收 ...
- socket聊天室(服务端)(多线程)(TCP)
#include<string.h> #include<signal.h> #include<stdio.h> #include<sys/socket.h&g ...
- C#服务端判断客户端socket是否已断开的方法
刚开始,用Socket类的Connected属性来实现,却发现行不通,connected只表示 是在上次 还是 操作时连接到远程主机.如果在这之后[连接的另一方]断开了,它还一直返回true, 除非 ...
- Python3学习之路~8.3 socket 服务端与客户端
通过8.2的实例1-6,我们可以总结出来,socket的服务端和客户端的一般建立步骤: 服务端 步骤:1创建实例,2绑定,3监听,4阻塞,5发送&接收数据,6关闭. #Author:Zheng ...
随机推荐
- [HNOI 2004]树的计数
Description 一个有n个结点的树,设它的结点分别为v1, v2, …, vn,已知第i个结点vi的度数为di,问满足这样的条件的不同的树有多少棵.给定n,d1, d2, …, dn,编程需要 ...
- [SDOI2011]计算器
Description 你被要求设计一个计算器完成以下三项任务: 1.给定y,z,p,计算Y^Z Mod P 的值: 2.给定y,z,p,计算满足xy≡ Z ( mod P )的最小非负整数: 3.给 ...
- CodeForces346 C. Number Transformation II
C. Number Transformation II time limit per test 1 second memory limit per test 256 megabytes input s ...
- Codeforces Round#432 简要题解
来自FallDream的博客,未经允许,请勿转载,谢谢. Div2A 小判断题 Div2B 小判断题,合法的条件是|AB|=|BC|且三点不共线 Div1A 类比二维.三维空间,可以猜测n太大的时候没 ...
- hdu 3939(勾股+容斥)
题意: 给定一个整数L(L<=1e12),计算(x,y,z)组的个数.其中x<y<z,x^2+y^2=z^2,gcd(x,y)==1,gcd(x,z)==1,gcd(y,z)==1. ...
- Android智能手机中各种音频场景下的audio data path
上一篇文章(Android智能手机上的音频浅析)说本篇将详细讲解Android智能手机中各种音频场景下的音频数据流向,现在我们就开始.智能手机中音频的主要场景有音频播放.音频录制.语音通信等.不同场景 ...
- Linux学习之CentOS(一)--CentOS6.5环境搭建
一.前言 作为一个从事运维工作好几年的老运维来说,linux系统怎能不学呢?所以,这几天自己准备学习一下linux操作系统.废话不多说,直奔主题. 要学linux开发,首先得要安装linux系统吧,这 ...
- easyui datagrid 排序问题
$('#dg').datagrid({ remoteSort:false,④ sortName:'sysfield', ① sortOrder:'desc',② columns:[[ {field ...
- 忘记Jenkins管理员密码的解决办法
一.admin密码未更改情况 1.进入\Jenkins\secrets目录,打开initialAdminPassword文件,复制密码: 2.访问Jenkins页面,输入管理员admin,及刚才的密码 ...
- Spring Boot 参数校验
1.背景介绍 开发过程中,后台的参数校验是必不可少的,所以经常会看到类似下面这样的代码 这样写并没有什么错,还挺工整的,只是看起来不是很优雅而已. 接下来,用Validation来改写这段 2.Spr ...