网络原理 TCP与UDP协议

 博主主页: 码农派大星.

    数据结构专栏:Java数据结构

 数据库专栏:MySQL数据库

JavaEE专栏:JavaEE

关注博主带你了解更多数据结构知识

1.应用层

之前编写完了基本的 java socket ,要知道,我们之前所写的所有代码都在应⽤层,都是为了 完成某项业务.

应用层是我们以后工作开发中经常用到的,主要涉及两种情况:

1.使用别人已经创建好的应用层协议(比如http)

2.自己定义应用层协议:

1)明确前后端交互过程中,需要传递哪些信息

2)明确组织这些信息的格式

针对信息组织方式有很多种(确保前端后端是同一种方式)

关于组织数据的格式:

1.xml

通过标签来组织数据

<request>
	<userID>10</userID>
	<position>E45I60</position>
</request>

优点:可读性提高
缺点:标签写起来非常繁琐,传输的时候消耗额外网络带宽

2.json 

当前使用非常主流的网络通信的数格式

通过键值对来组织数据

{
	"userID":"10",
	"position":"E40I60"
}

优点可读性较高,比xml简洁
缺点:传输的时候消耗额外网络带宽

3.yml(yaml)

强制要求了数据的格式

request:
   userld: 1001;
   position:"E60N45"

优点:可读性非常高,不额外消耗带宽

4.google protobuffer

前三个方案,都是关注可读性, protobuffer关注性能,牺牲了可读性(通过二进制的方式组织数据)

而protobuffer直接通过"位置"约定字段的含义,不需要传输key的名字,也会针对传输的数值,进行二进制的编码,起到一些"压缩"效果,极大缩短了传输的数据体积,带宽消耗就越小,效率越高.

2.传输层

传输层包含两个重要的协议UDP和TCP。
UDP:无连接,不可靠,面向数据报,全双工
TCP:有连接,可靠,面向字节流,全双工


端口号:占2个字节写一个服务器的时候必须手动指定一个端口号,用来区分不同程序。但写客户端的时候不用手动指定,系统会自动分配。同一时刻,同一个机器上,同一个协议,一个端口只能被一个进程绑定,一个进程可以绑定多个端口
1-1023称为知名端口号,给一些比较知名的服务器使用例如:22为ssh服务器,80为http协议,443为https服务器。1024-65535为普通端口号。

1.UDP协议

UDP报头:一共占8个字节,每一个部分都各占两个字节。

UDP报文长度:占2个字节,最长65535即64kb,这个长度是定长的,不能最初修改。 

校验和: 网络传输过程中,受到环境因素(电信号,电磁波,光信号)的影响,使里面的传输信号发生改变,校验和存在的目的就是为了"发现"或"纠正",这样的错误.

随着业务发展,UDP的64KB已经不够满足业务要求了 ,所以TCP就很好来解决,并且对长度就没有限制了,自身也有可靠传输机制,代码修改成本也比较低

2.TCP协议

TCP全称为"传输控制协议(Transmission Control Protocol"),要对数据的传输进⾏⼀个详细的控制

源/⽬的端⼝号:表⽰数据是从哪个进程来,到哪个进程去; 

32位序号/32位确认号:    后面介绍  ;

4位TCP报头⻓度:表⽰该TCP头部有多少个32位bit(有多少个4字节);所以TCP头部最⼤⻓度是15 * 4=60

保留(6)位: 充分吸取UDP报文长度无法扩展的教训,保留(6)位用来考虑未来的可扩展性,用来未来新增某个属性或者某个属性长度不够用,就可把保留位拿出来用.

6位标志位:

◦ URG:紧急指针是否有效

◦ ACK:确认号是否有效

◦ PSH:提⽰接收端应⽤程序⽴刻从TCP缓冲区把数据读⾛

◦ RST:对⽅要求重新建⽴连接;我们把携带RST标识的称为复位报⽂段

◦ SYN:请求建⽴连接;我们把携带SYN标识的称为同步报⽂段

◦ FIN:通知对⽅,本端要关闭了,我们称携带FIN标识的为结束报⽂段

2.1.确认应答

TCP的一个重要机制就是可靠传输,可靠传输就是当发送方把信息发出去,能够知道接收方是否接受了数据,一旦发现对方没有接受数据,那么发送方就会通多一定的手段来进行补救。

当发送方把信息发出去,接收方如收到信息,那么就会返回一个应答报文给发送方,如果发送方收到了这个报文,那么就证明信息发送成功了。但是在这个过程中可能会出现一些问题:例如我连续发送了两次请求,但是我后发送的消息却先响应了。 

为了避免出现这样的情况,TCP就需要确保应答报文和发出去的数据能够相互对应,即使出现后发先至的现象时,仍然能够按照正常的顺序来理解数据:我们发数据的时候就给数据编一个号,同时接收端做出响应也编一个号,这个时候就需要用到报头中的32位序号和32位确认序号。 

 --------------------------------------------------完美分割线------------------------------------------------------------

TCP将每个字节的数据都进⾏了编号.即为序列号 

每⼀个ACK都带有对应的确认序列号,意思是告诉发送者,我已经收到了哪些数据;下⼀次你从哪⾥开始发.

 

接收方这边调用read的时候如果没有数据,就会阻塞等待(前面代码写的是scanner读取, 本质上就是调用InputStream.read),此时虽然1001-2000这个数据到了,但是B不会让read解除阻塞,读到1001-2000这个数据还是要继续阻塞等待.直到说1-1000这个数据到达之后,read才会解除阻塞才会读取到1-1000,1001-2000,2001-3000数据,确保发送方write的顺序和接收方read的顺序是始终保持一致的

 B接收方这边,操作系统内核里,会有一段内存空间,作为"内存缓冲区",收到的数据,就会先在接收缓冲区排队等待,只到开头的数据到了,应用程序才能真正读取到里面的数据.

2.2 超时重传 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值