当前位置:   article > 正文

计算机网络二(TCP/IP模型)

计算机网络二(TCP/IP模型)

目录

1:TCP/IP模型

1.1什么是TCP/IP

1.2在TCP/IP模型图例

2:详解TCP通信 

2.1三次握手创建:

2.2四次握手断开:

2.3为何什么3次握手创建,但是分手需要四次

3:socket通信代码实现

3.1什么是socket

3.2socket代码简单实现


1:TCP/IP模型

1.1什么是TCP/IP

tcp/ip是一个网络通信模型,以及整个网络传输协议家族,是互联网的基础通信架构。他被成为是tcp/ip协议族,简称tcp/ip。该协议家族的两个最核心的通信协议是TCP和IP协议

TCP(传输控制协议):主要用于规范数据怎么建立连接传输,怎么传输数据,

TCP

TCP是面向通信的协议,会建通过三次握手来建立连接,然后在传递数据,并且断开连接需要四次握手。并且在数据传输的时候会通过底层复杂的算法来对数据进行确认,确认机制,重传机制,拥塞机制,等保证数据的时序性和完整性。不容易丢失数据,只能用于端到端的通信。什么时候应该使用TCP: 当对网络通讯质量有要求的时候,比如:整个数据要准确无误的传递给对方,这往往用于一些要求可靠的应用,比如HTTP、HTTPS、FTP等传输文件的协议,POP、SMTP等邮件传输的协议,均使用了TCP协议。但是开销大

UDP

UDP是面向无连接的通讯协议,硬件之间不需要创建连接,UDP数据包括目的端口号和源端口号信息,由于通讯不需要连接,所以可以实现广播(广播的形式在局域网中大家都能都听到)发送,能够一对多,。UDP通讯时不需要接收方确认,属于不可靠的传输,可能会出现丢包现象,实际应用中要求程序员编程验证。UDP只用于特殊服务采用该协议。例如例如IP电话,视频会议

 

 

IP(网际协议):主要用于规范通信双方处于网络的地址,地址规范化

    IP层接受更底层网络接口层(网络接口层例如以太网设备驱动程序)发送的数据包,并且将数据发送给更高层的TCP或者UDP,相反IP层也会从TCP或者UDP接受数据传送到更底层,每一台设备在互联网上的IP都是唯一的。

UDP和TCP对比

1、TCP面向连接(如打电话要先拨号建立连接);UDP是无连接的,即发送数据之前不需要建立连接

2、TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付 Tcp通过校验和,重传控制,序号标识,滑动窗口、确认应答实现可靠传输。如丢包时的重发控制,还可以对次序乱掉的分包进行顺序控制。

3、UDP具有较好的实时性,工作效率比TCP高,适用于对高速传输和实时性有较高的通信或广播通信。

4.每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信

5、TCP对系统资源要求较多,UDP对系统资源要求较少。

 

我们在用Socket编程时,UDP协议要求包小于64K。TCP没有限定;虽然在传输层,TCP不会对数据长度作出限制, 由于TCP是数据流协议,因此不存在包大小的限制(暂不考虑缓冲区的大小),这是指在用send函数时,数据长度参数不受限制。而实际上,所指定的这段数据并不一定会一次性发送出去,如果这段数据比较长,会被分段发送,如果比较短,可能会等待和下一次数据一起发送。UDP协议要求包小于64K。

但是在网络层(IP) 中都会对数据超过1500字节做出拆分,分批发送。TCP保证顺序,但是UDP不保证顺序。

数据链路层以太网协议下TCP和IP的数据长度:

UDP 包的大小就应该是 1500 - IP头(20) - UDP头(8) = 1472(Bytes)
TCP 包的大小就应该是 1500 - IP头(20) - TCP头(20) = 1460 (Bytes)

1.2在TCP/IP模型图例

在上一章节中,我们理解了OSI(open system internation)七层网络模型,那么做在tcp/ip通信模型中会将整个网络划分为5层,以此对应OSI,图例如下。

 

2:详解TCP通信 

我们知道了TCP(传输控制协议)是实现端对端的通信,需要建立三次握手连接,来保证端到端的通道创建。

TCP/IP协议的详细信息参看《TCP/IP协议详解》三卷本。下面是TCP报文格式图:

 

上图中有几个字段需要重点介绍下:
  (1)序号:Seq序号,占32位,用来标识从TCP源端向目的端发送的字节流,发起方发送数据时对此进行标记。
  (2)确认序号:Ack序号,占32位,只有ACK标志位为1时,确认序号字段才有效,Ack=Seq+1。
  (3)标志位:共6个,即URG、ACK、PSH、RST、SYN、FIN等,具体含义如下:
  (A)URG:紧急指针(urgent pointer)有效。
  (B)ACK:确认序号有效。
  (C)PSH:接收方应该尽快将这个报文交给应用层。
  (D)RST:重置连接。
  (E)SYN:发起一个新连接。
  (F)FIN:释放一个连接。

需要注意的是:
  (A)不要将确认序号Ack与标志位中的ACK搞混了。
  (B)确认方Ack=发起方Req+1,两端配对。

2.1三次握手创建:

所谓三次握手(Three-Way Handshake)即建立TCP连接,就是指建立一个TCP连接时,需要客户端和服务端总共发送3个包以确认连接的建立。在socket编程中,这一过程由客户端执行connect来触发,整个流程如下图所示:

 

(1)第一次握手:Client将标志位SYN置为1,随机产生一个值seq=J,并将该数据包发送给Server,Client进入SYN_SENT状态,等待Server确认。
  (2)第二次握手:Server收到数据包后由标志位SYN=1知道Client请求建立连接,Server将标志位SYN和ACK都置为1,ack=J+1,随机产生一个值seq=K,并将该数据包发送给Client以确认连接请求,Server进入SYN_RCVD状态。
  (3)第三次握手:Client收到确认后,检查ack是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K+1,并将该数据包发送给Server,Server检查ack是否为K+1,ACK是否为1,如果正确则连接建立成功,Client和Server进入ESTABLISHED状态,完成三次握手,随后Client与Server之间可以开始传输数据了。

2.2四次握手断开:

三次握手耳熟能详,所谓四次挥手(Four-Way Wavehand)即终止TCP连接,就是指断开一个TCP连接时,需要客户端和服务端总共发送4个包以确认连接的断开。在socket编程中,这一过程由客户端或服务端任一方执行close来触发,整个流程如下图所示:

 

由于TCP连接时全双工的,因此,每个方向都必须要单独进行关闭,这一原则是当一方完成数据发送任务后,发送一个FIN来终止这一方向的连接,收到一个FIN只是意味着这一方向上没有数据流动了,即不会再收到数据了,但是在这个TCP连接上仍然能够发送数据,直到这一方向也发送了FIN。首先进行关闭的一方将执行主动关闭,而另一方则执行被动关闭,上图描述的即是如此。


(1)第一次挥手:Client发送一个FIN,用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态。
  (2)第二次挥手:Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态。
(3)第三次挥手:Server发送一个FIN,用来关闭Server到Client的数据传送,Server进入LAST_ACK状态。
  (4)第四次挥手:Client收到FIN后,Client进入TIME_WAIT状态,接着发送一个ACK给Server,确认序号为收到序号+1,Server进入CLOSED状态,完成四次挥手。

2.3为何什么3次握手创建,但是分手需要四次

由于TCP连接是全双工的的,因此,每个方向都必须要单独进行关闭简单来说。张三对说小红要分手(第一次),小红会把张三的东西还给张三(第二次),小红说可以跟张三分手(第三次),张三分手并把正式分手信息告诉小红(第四次)。

 

3:socket通信代码实现

3.1什么是socket

socekt是网络编程接口:socket被称作套接字,前边我们讲了TCP/IP模型,里边重要的协议TCP和UDP,那么TCP/IP也需要提供出来可以给程序员做网络开发的编程接口,这就是socket编程接口,http是轿车,提供了封装和显示数据的具体实现形式;socket就是发动机,提供网络通信的能力。

3.2socket代码简单实现

service端代码如下:

  1. package com.thit.socket;
  2. import java.io.InputStream;
  3. import java.net.ServerSocket;
  4. import java.net.Socket;
  5. public class Service1 {
  6. //代码为固定套路
  7. public static void main(String[] args) throws Exception {
  8. //补充:端口范围0-65535,0-1023为系统占用端口
  9. //服务端指定端口
  10. int port=65531;
  11. ServerSocket service=new ServerSocket(port);
  12. //service将一直等待连接的到来
  13. System.out.println("-----service启动了!---------");
  14. Socket socket=service.accept();
  15. InputStream inputStream=socket.getInputStream();
  16. byte[] bytes=new byte[1024];
  17. int len;
  18. StringBuilder sBuilder=new StringBuilder();
  19. while ((len=inputStream.read(bytes))!=-1) {
  20. sBuilder.append(new String(bytes, 0, len, "UTF-8"));
  21. }
  22. System.out.println("service接受的数据是:"+sBuilder);
  23. inputStream.close();
  24. socket.close();
  25. service.close();
  26. }
  27. }

客户端代码如下:

  1. package com.thit.socket;
  2. import java.io.IOException;
  3. import java.io.OutputStream;
  4. import java.net.Socket;
  5. public class Client1 {
  6. public static void main(String[] args) throws Exception, IOException {
  7. // TODO Auto-generated method stub
  8. String host="127.0.0.1";
  9. int port=65531;
  10. //创建端到端的连接
  11. Socket socket=new Socket(host, port);
  12. OutputStream outputStream=socket.getOutputStream();
  13. String msg="hello word!";
  14. outputStream.write(msg.getBytes("UTF-8"));
  15. outputStream.close();
  16. socket.close();
  17. }
  18. }

然后启动服务端和客户端,得到结果如下:

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/665884
推荐阅读
相关标签
  

闽ICP备14008679号