【网络编程】网络编程概念 | TCP和UDP的区别 | UDP数据报套接字编程 | Socket

文章目录

  • 网络编程
        • 一、什么是网络编程
          • 1.TCP和UDP的区别
        • 二、UDP数据报套接字编程
          • DatagramSocket
          • DatagramPacket
          • 回显服务器(echo server)

网络编程

一、什么是网络编程
  • 通过网络,让两个主机之间能够进行通信。基于通信来完成一定的功能。

​ 进行网络编程的时候,需要操作系统提供一组API,通过这些API来完成。这些API可以认为的应用层和传输层之间交互的路径。这些API称为Socket API。通过一套Socket API 可以完成不同主机、不同系统之间的网络通信。

​ 传输层提供的网络协议主要有两个:TCP、UDP。这两个协议的特性差异很大,会导致使用这两种协议进行网络编程,会存在一定的差别。系统就分别提供了两套API。

1.TCP和UDP的区别

1.TCP是有连接的,UDP是无连接的。

​ 连接是抽象的概念:此处的连接本质上,就是建立连接的双方,各自保存对方的信息。两台计算机建立连接,就是双方彼此保存了对方的关键信息。TCP要想通信,就需要先建立连接(保存对方信息)。存完之后才能通信。

如果A想和B建立连接,但是B拒绝了,通信就无法完成。

​ UDP想要通信,自己不会去保存对方信息。直接发送数据,不需要征求对方同意。(程序员调用UDP的Socket API会传东对方信息)

2.TCP是可靠传输的,UDP是不可靠传输的。

​ 在网络上进行通信,A给B发送消息。并不能保证100%送达。所以这里可靠传输的概念是:A给B发消息。A可以感知到,消息有没有到达B。就可以在发送失败时,采取一定的措施(尝试重传等)。但同时可靠传输的代价就是机制更复杂以及降低传输效率。

​ TCP就内置了可靠传输机制。

3.TCP是面向字节流的,UDP是面向数据报的。

​ TCP也是和文件操作一样,以字节为单位来进行传输。UDP则是按照数据报为单位进行传输。 UDP数据报有严格的格式。

网络通信数据的基本单位:1.数据报(Datagram)2.数据包(Packet)3.数据帧(Frame)4.数据段(Segment)

4.TCP和UDP都是全双工的。

一个信道,允许双向通信,就是全双工。一个信道,只能单向通信,就是半双工。

在代码中使用一个Socket对象,就可以发送数据也能接受数据。

二、UDP数据报套接字编程

​ Socket是操作系统中的概念,本质上是一种特殊的文件。就相当于把“网卡”这个设备抽象成了文件。后续往Socket文件中写数据,就相当于通过网卡发送数据。从Socket文件中读数据,就相当于通过网卡接收数据。把网络通信和文件操作进行统一。

DatagramSocket

在Java中,使用DatagramSocket这个类来表示系统内部的Socket文件。

DatagramSocket是UDP Socket,用来发送和接收UDP数据报

    public UdpEchoServer(int port) throws SocketException {//指定一个端口号socket = new DatagramSocket(port);//创建的socket对象绑定这个指定的端口。}

在这里插入图片描述

1.这里的send发送 和receive接收方法,传进的参数类型都是DatagramPacket数据报。

2.receive方法中,参数同样是一个“输出型参数”。

DatagramPacket
  • DatagramPacket这个类,表示一个UDP数据报。

    构造方法:

    1.只指定字节数组缓冲区

            DatagramPacket requestPacket = new DatagramPacket(new byte[4096], 4096);//用来承载从网卡中读到的数据。收到数据的时候需要搞一个内存空间来保存这个数据//DatagramPacket内部不能自行分配内存空间,需要程序员手动创建空间,交给DatagramPacket处理socket.receive(requestPacket);

2.指定字节数组缓冲区,同时制定一个InetAdress对象(包含了IP和端口号)

            DatagramPacket responsePacket = new DatagramPacket(response.getBytes(), //指定的数据response.getBytes().length, //数据的长度requestPacket.getSocketAddress());//发送来的地址就是要发送的地址。public synchronized SocketAddress getSocketAddress() {return new InetSocketAddress(getAddress(), getPort());}

3.指定字节数组缓冲区,指定IP + 端口号。

    	 DatagramPacket requestPacket = new DatagramPacket( request.getBytes(), request.getBytes().length,InetAddress.getByName(serverIp), serverPort);

​ UDP是面向数据报的,每次进行传输,都要以UDP数据报为基本单位。在DatagramSocket的方法中,接收和发送传入的参数就是DatagramPacket数据报类型。

回显服务器(echo server)
  • 写一个简单的客户端、服务器通信程序。单纯调用Socket API。从控制台上输入一个请求发送给服务器,服务器收到字符串后,原封不动返回给客户端并显示出来。

​ 服务器和客户端都需要创建Socket对象。但是 服务器的socket一般要显示的指定一个端口号。而客户端的socket一般不能显示指定。(不显示指定,系统会自动分配一个随机的端口)

​ 服务器上有哪些程序,都使用哪些端口,都是程序员可控的。写代码时就可以指定空闲的端口,给当前的服务器使用。相比之下,客户端不可控。交给系统分配一个空闲的端口给客户端。所以服务器需要手动指定端口。客户端要交个系统来分配一个空闲端口。

UdpEchoServer

1.读取请求并解析

2.根据请求计算响应(一个服务器最核心的步骤)

3.把响应写回客户端

4.打印一个日志,把这次数据交互的详情打印出来

public class UdpEchoServer {//1.先出创建DatagramSocket对象 :后续操作网卡的基础private DatagramSocket socket = null;public UdpEchoServer(int port) throws SocketException {//指定一个端口号socket = new DatagramSocket(port);//创建的socket对象绑定这个指定的端口。}/*** 通过这个方法启动服务器*/public void start() throws IOException {System.out.println("服务器启动!");//在服务器程序中,经常出现while true的代码while (true) {//1.读取请求并解析DatagramPacket requestPacket = new DatagramPacket(new byte[4096], 4096);//用来承载从网卡中读到的数据。收到数据的时候需要搞一个内存空间来保存这个数据//DatagramPacket内部不能自行分配内存空间,需要程序员手动创建空间,交给DatagramPacket处理socket.receive(requestPacket);//读取数据,并填充进DatagramPacket,如果没有接收到数据报,receive方法会阻塞等待//此时是以二进制的形式存到DatagramPacket中,需要把二进制转换成字符串String request = new String(requestPacket.getData(), 0, requestPacket.getLength());//获取到字符数组,取[0,getLength]区间内的字节,构造成String. getLength不是4096,是实际的收到的数据长度//2.根据请求计算响应(一个服务器最核心的步骤)//由于此处是回显服务器,请求是啥样,响应就是啥样。String response = process(request);//3.把响应写回客户端//创建一个响应对象,DatagramPacket,往对象里构造刚才的数据,再通过send进行返回。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 {UdpEchoServer server = new UdpEchoServer(9090);server.start();}
  • 需注意的是,这里并没有写close.因为socket是文件描述符表的一个表项,文件描述符表在PCB上(跟随进程)。
  • socket在整个程序运行的过程中都需要使用,不能提前关闭。当不在再需要时,意味着程序就要结束了,进程结束,文件描述符表就会销毁。随着销毁,被系统自动回收
public class UdpEchoClient {private DatagramSocket socket = null;private String serverIp = "";private int serverPort = 0;public UdpEchoClient(String ip, int port) throws SocketException {//客户端的socket对象的端口,由系统自动分配socket = new DatagramSocket();//由于UDP不会持有对端的信息,需要在应用程序里,把对端的情况记录下来。serverIp = ip;serverPort = port;}public void start() throws IOException {System.out.println("客户端启动!");Scanner scanner = new Scanner(System.in);while (true) {//1.从控制台读取数据,作为请求System.out.print("->");String request = scanner.next();//2.把请求内容构造成DatagramPacket对象,再发给服务器DatagramPacket requestPacket = new DatagramPacket(request.getBytes(), request.getBytes().length,InetAddress.getByName(serverIp), serverPort);//把转换字符串ipsocket.send(requestPacket);//3.尝试读取服务器返回的响应DatagramPacket responsePacket = new DatagramPacket(new byte[4096],4096);socket.receive(responsePacket);//4.把响应,转换成字符串,并显示出来String response = new String(responsePacket.getData(),0,responsePacket.getLength());System.out.println(response);}}public static void main(String[] args) throws IOException {UdpEchoClient client = new UdpEchoClient("127.0.0.1",9090);client.start();}

1.服务器先启动,服务器启动之后,就会进入循环,执行到receive这里并进行阻塞

2.客户端开始启动,也会先进入while循环,执行到scanner.next,进行阻塞。当用户输入完成后,next就会返回,从而构造请求数据并进行发送给服务器。

3.服务器从receive中返回,进一步执行解析请求为字符串,执行process操作,执行send操作。

与此同时,客户端继续往下执行,执行到receive等待服务器的响应,进行阻塞。

4.客户端收到从服务器返回的数据后,就会从receive中返回,执行打印

5.服务器完成一次循环后,有执行到receive进行阻塞。客户端完成一次循环后,又执行到scanner.next进入阻塞,直到用户进行输入。

点击移步博客主页,欢迎光临~

偷cyk的图

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/3425.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2.7设计模式——Proxy 代理模式(结构型)

意图 为其它对象提供一种代理以控制这个对象的访问。 结构 Proxy保存一个引用使得代理可以访问实体;提供一个与Subject的接口相同的接口,使代理可以用来替代实体;控制实体的存取,并可能负责创建和删除它;其他功能依赖…

STCAD转换 晶联讯1353(5VLCD)显示

/***晶联讯1353(5VLCD)显示调节电位器参数变化***/ /******2018 6 30 08:50*L252 CODE 1339 ******/ /***变频器 PWM2017 5 6板测试AD晶联讯1353*****/ #include <reg52.h> // #define uint unsigned int …

[实验]Keil 4下仿真三星2440A芯片的汇编及CPIO控制实验

一、安装Keil uVision4 (详细安装过程忽略) 点击finish完成安装 二、新建项目&#xff0c;导入项目文件 选择对应的芯片&#xff0c;此处我们选择三星的S3C2440A&#xff0c;点击OK 在Source Group 1处右键&#xff0c;点击Add Files to "Sourcce Group 1’…将下图…

Linux之ebpf(1)基础使用

Linux之ebpf(1)基础使用 Author: Once Day Date: 2024年4月20日 一位热衷于Linux学习和开发的菜鸟&#xff0c;试图谱写一场冒险之旅&#xff0c;也许终点只是一场白日梦… 漫漫长路&#xff0c;有人对你微笑过嘛… 全系列文章可以参考专栏&#xff1a;Linux基础知识_Once-D…

非对称渐开线齿轮学习笔记分享

最近有小伙伴遇到了非对称渐开线齿轮的加工问题,花了些时间学习了解一下,下面是总结的学习笔记,有兴趣的朋友可以瞅瞅: 目录: 为什么要采用非对称? 非对称有什么优点? 非对称齿形如何加工? 非对称齿轮怎么测量? 非对称齿轮建模 为什么要采用非对称? 现在的传动要求…

关于浏览器360导航无法更改

当前环境场景&#xff1a; 浏览器&#xff1a;Microsoft Edge 版本 121.0.2277.106 (正式版本) (64 位) 系统&#xff1a;Windows 11 家庭中文版 23H2 问题描述 首先出现这种情况会让我们非常的气愤但是又束手无策&#xff0c;看到这个页面简直就恨的牙根痒痒&#xff0c;但是…

14.MMD导入Blender及贴图步骤

MMD导出.abc文件 在MMD十周年桥版本导入一个人物模型&#xff0c;这里导入仆人 注意MMD的路径不能有中文 点击上面的MMDBridge 设定 第一个选择blender by 第二个选择实行 这里是选择帧数范围和帧率 帧率一定要是30&#xff0c;不然后面可能会出问题 点击文件导出视频…

宁夏回族自治区工程技术系列专业技术职称评审条件

宁夏回族自治区工程技术系列专业技术职称评审条件链接http://222.75.70.73:8001/zcps/HomepageNotices.do?methodfwdPageNotice&strbm90aWNlaWQ9MjcxMjAyMDAzMTMwNjAxMjk2NTc类别基本条件业绩成果备注助理工程师1.本专业&#xff08;或相近专业&#xff09;中专毕业&#…

C/C++开发,opencv-ml库学习,支持向量机(SVM)应用

目录 一、OpenCV支持向量机&#xff08;SVM&#xff09;模块 1.1 openCV的机器学习库 1.2 SVM&#xff08;支持向量机&#xff09;模块 1.3 支持向量机&#xff08;SVM&#xff09;应用步骤 二、支持向量机&#xff08;SVM&#xff09;应用示例 2.1 训练及验证数据获取 2…

Gin+WebSocket实战——在线聊天室WebSocketDemo详细使用教程

文章目录 仓库地址项目简介如何使用 仓库地址 Github&#xff1a;https://github.com/palp1tate/WebsocketDemo 欢迎star&#xff01;&#x1f60e; 项目简介 利用 GinWebSocket 实现的在线聊天室Demo项目&#xff0c;支持加入/离开聊天室广播、给其他用户发送消息等。 如何…

STL——List常用接口模拟实现及其使用

认识list list的介绍 list是可以在常数范围内在任意位置进行插入和删除的序列式容器&#xff0c;并且该容器可以前后双向迭代。 list的底层是双向链表结构&#xff0c;双向链表中每个元素存储在互不相关的独立节点中&#xff0c;在节点中通过指针指向其前一个元素和后一个元素…

【C++】抽象类 与 C++

基础 C中没有抽象类的概念C中通过纯虚函数实现抽象类纯虚函数只是定义原型的成员函数一个类中存在纯虚函数就成为了抽象类 纯虚函数语法 class Shape {public:virtual double area() 0;// 0 用于告诉编译器当前是声明纯虚函数&#xff0c;因此不需要定义函数体 };抽象类与纯虚…

系统思考—心智模式

如果你总是做你过去一直做的事&#xff0c;你将永远得到你一直得到的结果。——托尼罗宾斯 在1980年代早期&#xff0c;美国汽车公司的高层主管定期前往日本参观&#xff0c;想要了解日本汽车行业为何能超越美国。这些主管返回后常说&#xff1a;“他们没有让我们看到真正的工…

工作任务管理平台作品集源文件 figma格式UX/UI设计师作品集

交付文件&#xff1a;作品集源文件项目源文件包装样机源文件字体文件 交付格式&#xff1a;figma、psd 作品集文件页数&#xff1a;28页 项目文件页数&#xff1a;12页&#xff08;Web&#xff09;12页&#xff08;App&#xff09; 以下重点哦&#xff0c;请认真阅读&#…

碰撞检测与相交测试-unity碰撞检测和相交测试的实现原理

Unity中的碰撞检测和相交测试是通过物理引擎来实现的。Unity使用了基于迭代的动态物理引擎&#xff0c;其中包含了一些常用的碰撞检测算法和相交测试算法。 碰撞检测是指判断两个物体是否发生了碰撞&#xff0c;而相交测试是指判断两个物体是否有交集。 在Unity中&#xff0c…

Halcon 3D 使用3D ROI截取模型

Halcon 3D 使用3D ROI截取模型 链接:https://pan.baidu.com/s/1UfFyZ6y-EFq9jy0T_DTJGA 提取码:ewdi * 1.读取图片 ****************

《R语言与农业数据统计分析及建模》学习——方差分析

方差分析是研究一种或多种因素的变化对试验结果的观测值是否有显著影响&#xff0c;从而找到较优试验条件或生产条件的一种常用数理统计方法。 方差分析根据平方和的加和原理&#xff0c;利用F检验&#xff0c;进而判断试验因素对试验结果的影响是否显著。 分为&#xff1a;单因…

CMake+qt+Visual Studio

#使用qt Creator 创建Cmake 项目,使用Cmake Gui 生成sln 工程&#xff0c;使用Visual Studio 开发 ##使用qt Creator 创建CMake项目 和创建pro工程的步骤一致&#xff0c;只是在选择构建系统的步骤上选择CMake,接下来步骤完全相同 工程新建完成之后&#xff0c;构建cmake 项…

公司服务器中的kafka消息中间件挂了,我是如何修复的?

今天的公司的system系统服务在运行过程中&#xff0c;提示连接不上kafuka的消息中间件。但是负责kafka的同事已经离职了&#xff0c;询问公司开发也不知道如何处理&#xff0c;我是如何重启kafka消息中间件使system系统服务正常运行&#xff1f; 查看kafka的安装位置 在下面的…

Java基础:设计模式之原型模式

原型模式是一种创建型设计模式&#xff0c;它允许我们通过复制现有的对象来创建新的对象&#xff0c;而不是每次都通过构造函数新建。这种模式适用于那些创建新对象成本较高或者构造过程复杂的情况。在原型模式中&#xff0c;一个对象通过实现Cloneable接口并重写其clone()方法…