java socket数据传输_【Java TCP/IP Socket】深入剖析socket——数据传输的底层实现

底层数据结构

如果不理解套接字的具体实现所关联的数据结构和底层协议的工作细节,就很难抓住网络编程的精妙之处,对于TCP套接字来说,更是如此。套接字所关联的底层的数据结构集包含了特定Socket实例所关联的信息。比附,套接字结构除其他信息外还包含:

1、该套接字所关联的本地和远程互联网地址和端口号。

2、一个FIFO(First Im First Out)队列,用于存放接收到的等待分配的数据,以及一个用于存放等待传输的数据的队列。

3、对于TCP套接字,还包含了与打开和关闭TCP握手相关的额定协议状态信息。

e7263f35dffbf174132a1432cc3258ba.png

了解这些数据结构,以及底层协议如何对其进行影响是非常有用的,因为它们控制了各种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()方法的缓冲区的大小。

示例分析

为了展示这种情况,考虑如下程序:

ff7f034dd317c84428604afc26731245.png

其中,圆点代表了设置缓冲区数据的代码,但不包含对out.write()方法的调用。这个TCP连接向接收端传输8000字节,在连接的接收端,这8000字节的分组方式取决于连接两端的out.write()方法和in.read()方法的调用时间差,以及提供给in.read()方法的缓冲区的大小。

下图展示了3次调用out.write()方法后,另一端调用in.read()方法前,以上3个队列的一种可能状态。不同的阴影效果分别代表了上文中3次调用write()方法传输的不同数据:

62c599a5f46b8003fe3586935f96724c.png

现在假设接收者调用read()方法时使用的缓冲区数组大小为2000字节,read()调用则将把RecvQ中的1500字节全部移动到数组中,返回值为1500。注意,这些数据中包含了第一次和第二次调用write()方法时传输的字节,再过一段时间,当TCP连接传完更多数据后,这三部分的状态可能如下图所示:

5247324eb46578385f99fc9a8576b358.png

如果接收者现在调用read()方法时使用4000字节的缓冲区数组,将有很多字节从RecvQ队列转移到Delivered队列中,这包括第二次调用write()方法时剩下的1500字节加上第三次调用write()方法的钱2500字节。此时,队列的状态如下图:

9cbbc4130183eea663bda2ef171a7d86.png

下次调用read()方法返回的字节数,取决于缓冲区数组的大小,亦及发送方套接字通过网络向接收方实现传输数据的时机。数据从sendQ到RecvQ缓冲区的移动过程对应用程序协议的设计有重要的指导性。

深入浅出--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” ...

随机推荐

mysql配置优化测试

http://bjlfp.blog.163.com/blog/static/77368461201211695924524/ 感觉真不错啊.观察几天看看

从零开始搭建Jenkins+Docker自动化集成环境

本文只简单标记下大概的步骤,具体搭建各个部分的细节,还请自行搜索.第一.二部分只是对Jenkins和Docker的简单介绍,熟悉的同学请直接跳到第三部分. 一.关于Jenkins Jenkins简介 ...

bzoj 4545: DQS的trie

Description DQS的自家阳台上种着一棵颗粒饱满.颜色纯正的trie. DQS的trie非常的奇特,它初始有n0个节点,n0-1条边,每条边上有一个字符.并且,它拥有极强的生长力:某个i时刻 ...

项目管理——WBS工作分解法

首先我们要了解什么是WBS工作分解法 工作分解结构(Work Breakdown Structure,简称WBS)跟因数分解是一个原理,就是把一个项目,按一定的原则分解,项目分解成任务,任务再分解成一 ...

缓存--Redis

Redis redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合).zset(sorte ...

Selenium Web 自动化 - 项目实战(一)

Selenium Web 自动化 - 测试框架(一) 2016-08-05 目录 1 框架结构雏形2 把Java项目转变成Maven项目3 加入TestNG配置文件4 Eclipse编码修改5 编写代 ...

《HTTP - 基于http的认证》

推荐一首歌 - 好吧,今天刚入职第二天,也没听歌. 哈哈哈哈. 1:何为认证? - 其实这个问题就比较宽泛了,总的来说,就是你有证明你身份的标识. - 和人类社会一样,你花了钱想看一场场演唱会,但是谁 ...

AltiumDesigner 网络标号放置技巧

我们在使用AD画图的过程中,灵活的使用一些小技巧可以使我们的工作事半功倍,今天给大家介绍一种在画原理图过程中的小技巧. 我们在画原理图过程中经常会放置网络标号,尤其是很多芯片管脚上,例如现在我需要在这 ...

python第三十六课——2.迭代器对象

满足前提: 1).必须是一个可迭代对象 2).可以被next()所作用的 举例: generator... 高效的检测一个对象是否是迭代器对象 需要使用collections模块中的Iterator类 ...

Oracle SQL部分练习题

SQL练习题        注:查询列表不建议用 “*” 1.列出至少有一个雇员的所有部门: a. select * from dept where deptno in(select distinct ...

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值