TCP与UDP详解大全

TCP/UDP头部

TCP头部

  1. 源端口、目的端口:数据的分用通过端口实现
  2. 序号:从0~2^32 - 1循环使用、每个字节一个序号、报文段第一个字节序号称为“报文段序号”
  3. 确认号:接收方期待收到对方下一个报文段的报文段序号,确认号数值设置在确认分组当中
  4. 数据偏移:数据部分距离报文起始位置,即首部长度,最大为60字节
  5. 保留:目前置为0,无用
  6. 控制位
  • 紧急URG:URG = 1时,表明报文中有紧急数据,需要与紧急指针配合
  • 确认ACK:建立TCP连接后,所有报文段ACK置为1,表明确认号有效
  • 推送PSH:当PSH = 1,数据报直接发送。PSH = 0,缓存填满才发送
  • 复位RST:RST = 1,TCP连接需要释放并重新建立
  • 同步SYN:
    SYN = 1、ACK = 0,该报文段是连接请求报文段
    SYN = 1、ACK = 1,该报文段是同意连接报文段
  • 终止FIN:FIN = 1,该报文段请求释放连接
  1. 窗口:接收方允许发送方传送的数据量
  2. 检验和:与UDP用户数据报一样
  3. 紧急指针:紧急指针指出紧急数据的位置
  4. 选项:窗口扩大、时间戳

在这里插入图片描述
UDP头部

  1. 源端口:接收方回信时选用、不需要时可用全0
  2. 目的端口:必须使用
  3. 长度:整个报文长度
  4. 检验和:检测整个报文
  5. 伪首部:当UDP数据报需要进行检验时,会在首部生成临时的伪首部。但是伪首部只是UDP暂时的,不属于UDP数据报组成

在这里插入图片描述

TCP/UDP区别

TCP面试连接,UDP面向无连接

  1. TCP面向连接:数据传输前使用三次报文握手建立TCP 连接,TCP 连接建立成功后才能进行数据传输,数据传输结束后使用四报文挥手来释放TCP连接。
  2. UDP面向无连接:双方进行通信,可以随时发送数据

TCP是可靠的,UDP是不可靠的

  1. TCP是可靠的:通过接收确认和重传机制,TCP保证数据的正确性以及顺序
  2. UDP是不可靠的:UDP不保证数据的正确性、顺序,甚至还可能丢包

传输方式

  1. TCP:只能支持一对一
  2. UDP: 不仅支持一对一的传输方式,同样支持一对多,多对多,多对一的方式,也就是说 UDP 提供了单播,多播,广播的功能。

TCP面向字节流,UDP面向报文

  1. TCP面向字节流:TCP基于流的传输表示TCP不认为消息是一条一条的
  2. UDP面向报文:UDP基于报文的传输标识UDP认为消息是一条一条独立的消息

TCP头部开销大,UDP头部开销小

  1. TCP头部开销大:至少20个字节
  2. UDP头部开销小:只有8个字节

TCP具有拥塞控制,UDP没有拥塞控制

  1. TCP具有拥塞控制
  2. UDP没有拥塞控制:因此网络出现拥塞不会使源主机的发送速率降低

应用场景

  1. TCP适用要求可靠传输的应用(文件传输)
  2. UDP适用实时应用(直播、视频会议、IP电话)

各自问题

  1. TCP会出现粘包问题:TCP是面向连接的,所以在TCP看来,并没有把消息看成一条条的,而是全部消息在TCP眼里都是字节流,因此容易把多个消息混在一起后,TCP就分不清了
  2. UDP会出现丢包问题

TCP/UDP项目实战

TCP
TcpClientDemo01

public class TcpClientDemo01 {
    public static void main(String[] args) throws IOException {
        //1. 创建连接127.0.0.1:9999的Socket
        InetAddress serverIp = InetAddress.getByName("127.0.0.1");
        int port = 9999;
        Socket socket = new Socket(serverIp,port);

        //2. 创建对127.0.0.1:9999输出内容的输出流
        OutputStream os = socket.getOutputStream();
        os.write("你好".getBytes());

        //3. 关闭socket与IO流
        os.close();
        socket.close();
    }
}

TcpServerDemo01

public class TcpServerDemo01 {
    public static void main(String[] args) throws IOException {
        //1. 创建服务器Socket用于监听客户端Socket
        ServerSocket serverSocket = new ServerSocket(9999);

        //2. 创建连接监听到客户端的Socket
        Socket socket = serverSocket.accept();

        //3. 创建连接被监听的Socket的输入流
        InputStream is = socket.getInputStream();
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len;
        while((len = is.read(buffer))!=-1){
            baos.write(buffer,0,len);
        }
        System.out.println(baos.toString());

        //4. 关闭socket与IO流
        baos.close();
        is.close();
        socket.close();
        serverSocket.close();
    }
}

UDP
UdpClientDemo01

public class UdpClientDemo01 {
    public static void main(String[] args) throws IOException {
        //1. 建立一个Socket
        DatagramSocket socket = new DatagramSocket();

        //2. 建立数据报
        String msg = "你好呀";
        InetAddress localhost = InetAddress.getByName("127.0.0.1");
        int port = 9090;
        DatagramPacket packet = new DatagramPacket(msg.getBytes(),0,msg.getBytes().length,localhost,port);

        //3. 发送数据报
        socket.send(packet);

        //4. 关闭socket
        socket.close();
    }
}

UdpServerDemo01

public class UdpServerDemo01 {
    public static void main(String[] args) throws IOException {
        //1. 建立一个socket
        DatagramSocket socket = new DatagramSocket(9090);

        //2. 接收数据报
        byte[] buffer = new byte[1024];
        DatagramPacket packet = new DatagramPacket(buffer,0,buffer.length);

        socket.receive(packet);

        System.out.println(new String(packet.getData(),0, packet.getLength()));

        socket.close();
    }
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值