【Java TCP/IP Socket】深入剖析socket——数据传输的底层实现
底层数据结构
如果不理解套接字的具体实现所关联的数据结构和底层协议的工作细节,就很难抓住网络编程的精妙之处,对于TCP套接字来说,更是如此。套接字所关联的底层的数据结构集包含了特定Socket实例所关联的信息。比附,套接字结构除其他信息外还包含:
1、该套接字所关联的本地和远程互联网地址和端口号。
2、一个FIFO(First Im First Out)队列,用于存放接收到的等待分配的数据,以及一个用于存放等待传输的数据的队列。
3、对于TCP套接字,还包含了与打开和关闭TCP握手相关的额定协议状态信息。
了解这些数据结构,以及底层协议如何对其进行影响是非常有用的,因为它们控制了各种Socket对象行为的各个方面。例如,由于TCP提供了一种可信赖的字节流服务,任何写入Socket和OutpitStream的数据副本都必须保留,直到连接的另一端将这些数据成功接收。向输出流写数据并不意味着数据实际上已经被发送——它们只是被复制到了本地缓冲区,就算在Socket的OutputStream上进行flush()操作,也不能保证数据能够立即发送到信道。此外,字节流服务的自身属性决定了其无法保留输入流中消息的边界信息。
数据传输的底层实现
在使用TCP套接字时,需要记住的最重要的一点是:不能假设在连接的一端将数据写入输出流和在另一端从输入流读出数据之间有任何的一致性。尤其是在发送端由单个输出流的write()方法传输的数据,可能会通过另一端的多个输入流的read()方法获取,而一个read()方法可能会返回多个write()方法传输的数据。
一般来讲,我们可以认为TCP连接上发送的所有字节序列在某一瞬间被分成了3个FIFO队列:
1、SendQ:在发送端底层实现中缓存的字节,这些字节已经写入输出流,但还没在接收端成功接收。它占用大约37KB内存。
2、RecvQ:在接收端底层实现中缓存的字节,这些字节等待分配到接收程序——即从输入流中读取。它占用大约25KB内存。
3、Delivered:接收者从输入流已经读取到的字节。
当我们调用OutputStream的write()方法时,将向SendQ追加字节。
TCP协议负责将字节按顺序从SendQ移动到RecvQ。这里有重要的一点需要明确:这个转移过程无法由用户程序控制或直接观察到,并且在块中发生,这些块的大小在一定程度上独立于传递给write()方法的缓冲区大小。
接收程序从Socket的InputStream读取数据时,字节就从RecvQ移动到Delivered中,而转移的块的大小依赖于RecvQ中的数据量和传递给read()方法的缓冲区的大小。
示例分析
为了展示这种情况,考虑如下程序:
其中,圆点代表了设置缓冲区数据的代码,但不包含对out.write()方法的调用。这个TCP连接向接收端传输8000字节,在连接的接收端,这8000字节的分组方式取决于连接两端的out.write()方法和in.read()方法的调用时间差,以及提供给in.read()方法的缓冲区的大小。
下图展示了3次调用out.write()方法后,另一端调用in.read()方法前,以上3个队列的一种可能状态。不同的阴影效果分别代表了上文中3次调用write()方法传输的不同数据:
现在假设接收者调用read()方法时使用的缓冲区数组大小为2000字节,read()调用则将把RecvQ中的1500字节全部移动到数组中,返回值为1500。注意,这些数据中包含了第一次和第二次调用write()方法时传输的字节,再过一段时间,当TCP连接传完更多数据后,这三部分的状态可能如下图所示:
如果接收者现在调用read()方法时使用4000字节的缓冲区数组,将有很多字节从RecvQ队列转移到Delivered队列中,这包括第二次调用write()方法时剩下的1500字节加上第三次调用write()方法的钱2500字节。此时,队列的状态如下图:
下次调用read()方法返回的字节数,取决于缓冲区数组的大小,亦及发送方套接字通过网络向接收方实现传输数据的时机。数据从sendQ到RecvQ缓冲区的移动过程对应用程序协议的设计有重要的指导性。
转自:http://blog.csdn.net/ns_code/article/details/15813809
【Java TCP/IP Socket】深入剖析socket——数据传输的底层实现的更多相关文章
- 深入浅出--iOS的TCP/IP协议族剖析&&Socket
深入浅出--iOS的TCP/IP协议族剖析&&Socket 简介 该篇文章主要回顾--TCP/IP协议族中的TCP/UDP.HTTP:还有Socket.(--该文很干,酝酿了许久! ...
- iOS的TCP/IP协议族剖析&&Socket
原创文章,版权声明:自由转载-非商用-非衍生-保持署名 | Creative Commons BY-NC-ND 3.0 简介 该篇文章主要回顾--TCP/IP协议族中的TCP/UDP.HTTP:还有S ...
- 深入浅出-TCP/IP协议族剖析&&Socket
Posted by 微博@Yangsc_o 原创文章,版权声明:自由转载-非商用-非衍生-保持署名 | Creative Commons BY-NC-ND 3.0 #简介 该篇文章主要回顾–TCP/I ...
- TCP/IP、Http、Socket、XMPP-从入门到深入
TCP/IP.Http.Socket.XMPP-从入门到深入 终极iOS程序猿 2016-12-29 18:27 为了便于大家理解和记忆,我们先对这几个概念进行的介绍,然后分析他们的不同,再进行详细的 ...
- TCP/IP、Http、Socket的区别与关系
--TCP/IP.Http.Socket的区别与关系 --------------------------------------2014/05/14 网络由下往上分为 物理层.数据链路层.网络层.传 ...
- Python Web学习笔记之TCP/IP、Http、Socket的区别
经常在笔试.面试或者工作的时候听到这些协议,虽然以前没怎么涉及过,但至少知道这些是和网络编程密不可分的知识,作为一个客户端开发程序员,如果可以懂得网络编程的话,他的作用和能力肯定会提升一个档次.原因很 ...
- TCP/IP、Http、Socket 简单理解
转自:http://blog.csdn.net/guyan0319 https://blog.csdn.net/guyan0319/article/details/79404216 一. 什么是TCP ...
- TCP/IP Http 和Https socket之间的区别
TCP/IP Http 和Https socket之间的区别 TCP/IP是个协议组,它分为网络层,传输层和应用层, 在网络层有IP协议.ICMP协议.ARP协议.RARP协议和BOOTP协议. ...
- Java——TCP/IP超详细总结
网络的基础知识 一.协议 1.简介: 在计算机网络与信息通信领域里,人们经常提及“协议”一词.互联网中常用的具有代表性的协议有IP.TCP.HTTP等.而LAN(局域网)中常用的协议有IPX/SPX” ...
随机推荐
- [LUOGU] P4767 [IOI2000]邮局
https://www.luogu.org/problemnew/show/P4767 四边形不等式好题! 可以设f[i][j]表示前i个村庄,建了j个邮局的最小代价. 转移:f[i][j]=min{ ...
- python常用内置函数用法精要
用一个表格大致总结一下所有的内置函数用法,如下: 函数 功能简要说明 abs(x) 返回数字x的绝对值或复数x的模 all(iterable) 如果对于可迭代对象中所有元素x都等价于True,则返回T ...
- link与@import导入css样式区别
XML/HTML代码<link rel="stylesheet" rev="stylesheet" href="CSS文件" type ...
- 创建虚拟机、安装centos系统,xshell连接虚拟机
创建虚拟机 文件--->新建虚拟机--->自定义最高级 选择虚拟机兼容性: workstation12.0:限制少,而且兼容的多 稍后安装操作系统 选择Linux系统 可选择centos7 ...
- C++基本数据类型占字节数
32位编译器 char :1个字节char*(即指针变量): 4个字节(32位的寻址空间是2^32, 即32个bit,也就是4个字节.同理64位编译器)short int : 2个字节int: 4个 ...
- mysql参数讲解
MySQL配置参数详解: http://blog.csdn.net/wlzx120/article/details/52301383 深入理解mysql参数 http://blog.itpub.net ...
- tomcat 修改默认端口8080 为 80端口
首先,找到你的安装目录,如图: 打开server.xml文件,找到8080,如图: 将 8080 改成你想要的端口,如 80 即可.改完后,记得要重启tomcat! 将端口改成 80 后,访问就不需 ...
- NYOJ 311 完全背包
完全背包 时间限制:3000 ms | 内存限制:65535 KB 难度:4 描述 直接说题意,完全背包定义有N种物品和一个容量为V的背包,每种物品都有无限件可用.第i种物品的体积是c,价值是 ...
- OSQL 用法
osql中的启动参数如下: -?:列出osql各个参数的语法摘要. -U login_id:用来指出登录名称,登录名区分大小写. -P password:用来指出登录名称所对应的密码. -E:表示采用 ...
- 【Luogu】P3376网络最大流模板(Dinic)
最大流模板成为另一个被攻克的模板题. 今天QDC给我讲了一下Dinic,感觉很好懂.于是为了巩固就把这道题A掉了. 核心思想就是不断BFS分层,然后不断DFS找增广路.找不到之后就可以把答案累加输出了 ...