TCP VS UCP

2023-10-07 00:04
文章标签 vs tcp ucp

本文主要是介绍TCP VS UCP,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

程序员写网络程序,主要编写的应用层代码!

真正要发这个数据,需要上层协议调用下层协议,应用层要调用传输层,则传输层给应用层提供一组api,统称为:soket api

基于UDP的api

基于TCP的api

这两个协议差别很大!!提供的api的差异也很大!!

UDP:

  • 无连接:使用UDP通信的双方,不需要可以得存对端的相关信息
  • 不可靠传输:消息发了就发了,不关注结果(投递简历)
  • 面向数据报:以一个UDP数据报为基本单位
  • 全双工:一条路径,双向通信

TCP:

  • 有链接:使用TCP通信的双方,需要刻意保存对方的相关信息
  • 可靠传输:不是说发了就100%能够到达对方,尽可能的传输过去(自己知道没成功)(打电话)
  • 面向字节流:以字节为传输的基本单位,读写方式非常灵活
  • 全双工:一条路径,双向通信

在上述所说的连接:并不是拿一根绳子,把两个设备绑一块,而是一个”抽象的连接“,可以理解成通信双方,各自记录了对方的信息;比如:民政局领结婚证!!(男女双方建立连接)!!

全双工 VS 半双工

那么,有了上述的基础知识,我们先来了解一下UDP的api吧(比TCP的要简单!)

两个重要的方法:DatagramSocket()   DatagramPacket()

DatagramPacket() :这个对象是一个UDP数据报

DatagramSocket()  :Datagram:就是数据报;Socket说明这个对象是一个socket对象

socket对象相当于对应到系统中一个特殊的文件(socket文件)

socket文件并非对应到硬盘上的某个数据存储区域,而是对应到网卡,这个硬件设备!!

要想进行网络通信,就需要有socket文件这样的对象,借助这个socket文件对象,才能够间接的操作网卡!(遥控器)

往这个socket对象中写数据,相当于通过网卡发送数据

从这个socket对象中读数据,相当于通过网卡接收数据

那么,我们来看一下DatagramSocket()  的构造方法:

  1. DatagramSocket() :创建一个UDP数据报套接字的Socket,绑定到本机任意一个随机端口(一般用于客户端)
  2. DatagramSocket(int port):创建一个UDP数据报套接字的Socket,绑定到本机指定的端口下(一般用于服务端)

    这两个构造方法中,一个带参数,一个不带参数

    服务器这边的socket往往要关联一个具体的端口号!(必须要不变)

    客户端这边则不需要手动指定,系统自动分配即可!(不要求)

  3. void  receive(DatagramPacket  p)从此套接字接收数据报(如果没有接受到数据报,该方法就会阻塞等待)
  4. void  send(DatagramPacket  p)从此套接字发送数据报(不会阻塞等待,直接发送)
  5. void  close()关闭此数据报套接字(一定是socket/文件,确定不用了,才能使用该close())

socket也是文件,文件用完了就得记得关闭,否则会出现文件资源泄露的问题!!

那么,我们来看一下DatagramPacket() 的构造方法:

  1. DatagramPacket(byte[]  buf , int length) 构造一个DatagramPacket以用来接收数据报,接收的数据保存在字节数组(第一个参数buf)中,接收指定长度(第二个参数length)
  2. DatagramPacket(byte[]  buf , int offset , int length , SocketAddress address) 构造一个DatagramPacket以用来发送数据报,发送的数据为字节数组(第一个参数buf)中,从0到指定长度(第二个参数length),address指定目的主机的IP和端口号!!
    这个版本,需要显式的设置地址进去,通常要用来发送信息!!

那么,我们来基于UDP  Socket来写一个最简单的客户端服务器程序吧!!

回显服务器(echo server):客户端发了个请求,服务器返回一个一模一样的响应!

一个服务器:主要要做三个核心工作:

  1. 读取请求并解析
  2. 根据请求计算响应(省略)
  3. 把响应返回到客户端

主要代码:

服务器(读取请求,发送响应)

package network;import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;// UDP 版本的回显服务器
public class UdpEchoServer {// 网络编程, 本质上是要操作网卡.// 但是网卡不方便直接操作. 在操作系统内核中, 使用了一种特殊的叫做 "socket" 这样的文件来抽象表示网卡.// 因此进行网络通信, 势必需要先有一个 socket 对象.private DatagramSocket socket = null;// 对于服务器来说, 创建 socket 对象的同时, 要让他绑定上一个具体的端口号.// 服务器一定要关联上一个具体的端口的!!!// 服务器是网络传输中, 被动的一方. 如果是操作系统随机分配的端口, 此时客户端就不知道这个端口是啥了, 也就无法进行通信了!!!public UdpEchoServer(int port) throws SocketException {socket = new DatagramSocket(port);}public void start() throws IOException {System.out.println("服务器启动!");// 服务器不是只给一个客户端提供服务就完了. 需要服务很多客户端.while (true) {// 只要有客户端过来, 就可以提供服务.// 1. 读取客户端发来的请求是啥.//    receive 方法的参数是一个输出型参数, 需要先构造好个空白的 DatagramPacket 对象. 交给 receive 来进行填充.DatagramPacket requestPacket = new DatagramPacket(new byte[4096], 4096);socket.receive(requestPacket);// 此时这个 DatagramPacket 是一个特殊的对象, 并不方便直接进行处理. 可以把这里包含的数据拿出来, 构造成一个字符串.String request = new String(requestPacket.getData(), 0, requestPacket.getLength());// 2. 根据请求计算响应, 由于此处是回显服务器, 响应和请求相同.String response = process(request);// 3. 把响应写回到客户端. send 的参数也是 DatagramPacket. 需要把这个 Packet 对象构造好.//    此处构造的响应对象, 不能是用空的字节数组构造了, 而是要使用响应数据来构造.DatagramPacket responsePacket = new DatagramPacket(response.getBytes(), response.getBytes().length,requestPacket.getSocketAddress());socket.send(responsePacket);// 4. 打印一下, 当前这次请求响应的处理中间结果.System.out.printf("[%s:%d] req: %s; resp: %s\n", requestPacket.getAddress().toString(),requestPacket.getPort(), request, response);}}// 这个方法就表示 "根据请求计算响应"public String process(String request) {return request;}public static void main(String[] args) throws IOException {// 端口号的指定, 大家可以随便指定.// 1024 -> 65535 这个范围里随便挑个数字就行了.UdpEchoServer server = new UdpEchoServer(9090);server.start();}
}

客户端:发请求,接收响应

package network;import java.io.IOException;
import java.net.*;
import java.util.Scanner;// UDP 版本的 回显客户端
public class UdpEchoClient {private DatagramSocket socket = null;private String serverIp = null;private int serverPort = 0;// 一次通信, 需要有两个 ip, 两个端口.// 客户端的 ip 是 127.0.0.1 已知.// 客户端的 port 是系统自动分配的.// 服务器 ip 和 端口 也需要告诉客户端. 才能顺利把消息发个服务器.public UdpEchoClient(String serverIp, int serverPort) throws SocketException {socket = new DatagramSocket();this.serverIp = serverIp;this.serverPort = serverPort;}public void start() throws IOException {System.out.println("客户端启动!");Scanner scanner = new Scanner(System.in);while (true) {// 1. 从控制台读取要发送的数据System.out.print("> ");String request = scanner.next();if (request.equals("exit")) {System.out.println("goodbye");break;}// 2. 构造成 UDP 请求, 并发送//    构造这个 Packet 的时候, 需要把 serverIp 和 port 都传入过来. 但是此处 IP 地址需要填写的是一个 32位的整数形式.//    上述的 IP 地址是一个字符串. 需要使用 InetAddress.getByName 来进行一个转换.DatagramPacket requestPacket = new DatagramPacket(request.getBytes(), request.getBytes().length,InetAddress.getByName(serverIp), serverPort);socket.send(requestPacket);// 3. 读取服务器的 UDP 响应, 并解析DatagramPacket responsePacket = new DatagramPacket(new byte[4096], 4096);socket.receive(responsePacket);String response = new String(responsePacket.getData(), 0, responsePacket.getLength());// 4. 把解析好的结果显示出来.System.out.println(response);}}public static void main(String[] args) throws IOException {UdpEchoClient client = new UdpEchoClient("127.0.0.1", 9090);// UdpEchoClient client = new UdpEchoClient("42.192.83.143", 9090);client.start();}
}

对上述代码进行分析:

对于客户端:

  1. 服务器先启动,执行到receive进行阻塞
  2. 客户端运行之后,从控制台读取到数据,并进行send
  3. 客户端这边send之后,继续往下走,走到receive读取响应,会阻塞等待
  4. 客户端这边真正收到服务器send回来的数据之后,就会接解除阻塞,执行下面的打印操作
  5. 客户端继续进入下一轮循环,阻塞在Scanner.next这里,等待用户输入新的数据

对于服务器:

  1. 服务器先启动,执行到receive进行阻塞
  2. 客户端运行之后,从控制台读取到数据,并进行send
  3. 服务器这边,就从reserve返回,读取到请求数据(客户端发来的),往下走到process,生成响应,再往下走,到send,并且打印日志
  4. 进入下一轮循环,在此阻塞在receive,等待客户端下一个请求

小结一下瞬间开心:

客户端:

读取用户输入

构造请求并发送

客户端读取服务器响应

客户端把响应转成字符串并显示出来

服务器:

读取用户的请求

根据请求计算响应

把响应写回到客户端

因此:总的大致过程为:

这篇关于TCP VS UCP的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/154772

相关文章

QT实现TCP客户端自动连接

《QT实现TCP客户端自动连接》这篇文章主要为大家详细介绍了QT中一个TCP客户端自动连接的测试模型,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录版本 1:没有取消按钮 测试效果测试代码版本 2:有取消按钮测试效果测试代码版本 1:没有取消按钮 测试效果缺陷:无法手动停

Android平台播放RTSP流的几种方案探究(VLC VS ExoPlayer VS SmartPlayer)

技术背景 好多开发者需要遴选Android平台RTSP直播播放器的时候,不知道如何选的好,本文针对常用的方案,做个大概的说明: 1. 使用VLC for Android VLC Media Player(VLC多媒体播放器),最初命名为VideoLAN客户端,是VideoLAN品牌产品,是VideoLAN计划的多媒体播放器。它支持众多音频与视频解码器及文件格式,并支持DVD影音光盘,VCD影

【Go】go连接clickhouse使用TCP协议

离开你是傻是对是错 是看破是软弱 这结果是爱是恨或者是什么 如果是种解脱 怎么会还有眷恋在我心窝 那么爱你为什么                      🎵 黄品源/莫文蔚《那么爱你为什么》 package mainimport ("context""fmt""log""time""github.com/ClickHouse/clickhouse-go/v2")func main(

2024.9.8 TCP/IP协议学习笔记

1.所谓的层就是数据交换的深度,电脑点对点就是单层,物理层,加上集线器还是物理层,加上交换机就变成链路层了,有地址表,路由器就到了第三层网络层,每个端口都有一个mac地址 2.A 给 C 发数据包,怎么知道是否要通过路由器转发呢?答案:子网 3.将源 IP 与目的 IP 分别同这个子网掩码进行与运算****,相等则是在一个子网,不相等就是在不同子网 4.A 如何知道,哪个设备是路由器?答案:在 A

图解TCP三次握手|深度解析|为什么是三次

写在前面 这篇文章我们来讲解析 TCP三次握手。 TCP 报文段 传输控制块TCB:存储了每一个连接中的一些重要信息。比如TCP连接表,指向发送和接收缓冲的指针,指向重传队列的指针,当前的发送和接收序列等等。 我们再来看一下TCP报文段的组成结构 TCP 三次握手 过程 假设有一台客户端,B有一台服务器。最初两端的TCP进程都是处于CLOSED关闭状态,客户端A打开链接,服务器端

网络原理之TCP协议(万字详解!!!)

目录 前言 TCP协议段格式 TCP协议相关特性 1.确认应答 2.超时重传 3.连接管理(三次握手、四次挥手) 三次握手(建立TCP连接) 四次挥手(断开连接)  4.滑动窗口 5.流量控制 6.拥塞控制 7.延迟应答 8.捎带应答  9.基于字节流 10.异常情况的处理 小结  前言 在前面,我们已经讲解了有关UDP协议的相关知识,但是在传输层,还有

VS Code 调试go程序的相关配置说明

用 VS code 调试Go程序需要在.vscode/launch.json文件中增加如下配置:  // launch.json{// Use IntelliSense to learn about possible attributes.// Hover to view descriptions of existing attributes.// For more information,

linux下TCP/IP实现简单聊天程序

可以在同一台电脑上运行,在一个终端上运行服务器端,在一个终端上运行客户端。 服务器端的IP地址要和本地的IP相同,并分配端口号,客户端的默认设置为本地,端口号自动分配。 服务器端: #include <stdio.h>#include <stdlib.h>#include <errno.h>#include <string.h>#include <sys/types.

JAVAEE初阶第七节(中)——物理原理与TCP_IP

系列文章目录 JAVAEE初阶第七节(中)——物理原理与TCP_IP 文章目录 系列文章目录JAVAEE初阶第七节(中)——物理原理与TCP_IP 一.应用层重点协议)1. DNS2 .NAT3. NAT IP转换过程 4 .NAPT5. NAT技术的缺陷6. HTTP/HTTPS7. 自定义协议 二. 传输层重点协议 1 .UDP协议 2.1.1 UDP协议端格式 2.1.2 UD

深入理解TCP通信

这大概是自己博客上面第三次写TCP通信demo了,总是写同样的内容也不太好啊,不过每一次都比前一次进步一点。这次主要使用了VIM编辑工具、gdb调试、wireshirk、netstat查看网络状态。 参考《C++服务器视频教程》、《Unix网络编程》 一、VIM常用命令 vim server.cpp #打开一个文件:w 写入文件:wq 保存并退出:q! 不保存退出显示行号