网络编程套接字(socket api)

了解了网络的一些概念,接下来就要进行网络中的跨主机通信,了解网络中的一些API,这里谈到的API都是针对传输层进行的,这是因为我们编写的代码是在应用层,而传输层就是到了计算机内核中操作系统中已经实现好了的,编写网络编程代码就是调用系统API,将数据传输到传输层,传输层->物理层就由操作系统进行。

将应用层数据传输到传输层的这些API就叫做socket api(网络编程套接字),要将数据传输到传输层就要了解传输层中涉及到的协议:TCP,UDP,这两个协议涉及到两组不同的socket api,要分别进行讨论。

TCP:有连接,可靠传输,面向字节流,全双工。

UDP:无连接,不可靠传输,面向数据包,全双工。

连接:有无连接就是通信双方是否保存对方信息。

可靠/不可靠传输:可靠传输就是会在发出数据报后尽可能的保证能到达对端,不可靠就是在发出数据包后不管了。

全双工:一个信道,可以双向传输。

UDP socket

DatagramSocket

网卡:网卡等硬件设备就是通过文件进行封装的,通过网络发送数据,就是往网卡里接收数据;通过网络接收信息,就是往网卡里读取数据,封装网卡的文件,就是socket文件。

而创建一个DatagramSocket对象就是在操作系统中创建一个socket文件,通过这个对象写入数据,就是通过网卡发送数据;通过对象读取数据,就是通过网卡接收数据。

DatagramSocket中的一些方法receive(接收一个数据报),send(发送一个数据报),close。

DatagramPacket

datagrampacket代表着一个UDP中传输数据的基本单位,也就是一个数据报。

编写一个简单的网络程序

一个网络程序一般是由客户端和服务器构成的,这里只考虑一个客户端和一个服务器,并且服务器返回的响应就是请求的回显服务器(echo server)。

客户端(cilent):

1.从控制台读取请求。

 2.通过网络将请求发送给服务器。

3.从服务器读取返回的结果。

4.将返回的结果显示到控制台

服务器(server):

1.接收客户端发来的请求。

2.根据请求处理响应。

3.将响应发送回客户端。

代码实现

服务器编写思路:

首先要创建一个socket文件对象(DatagramSocket),接下来就要通过网卡进行接收请求,那么就要创建一个数据报对象DatagramPacket,将网卡里的数据读写到数据报中,再对数据报中的进行内容进行解析。

public class Server {private DatagramSocket datagramSocket = null;public Server(int port) throws SocketException {//这里添加的port指的是服务器的端口号,源端口号和目的端口号是相对的//要指定的是空闲的端口,如果指定已经使用过的端口,就会抛出异常datagramSocket = new DatagramSocket(port);}public void start() throws IOException {//启动服务器//1.接送客户端请求//1.1 创建一个空的数据报DatagramPacket datagramPacket = new DatagramPacket(new byte[4069],4069);//1.2 将请求读到一个空的数据报中,receive方法会将网卡内容读到数据报中,当没读到东西时就会阻塞datagramSocket.receive(datagramPacket);//1.3 将数据报中二进制的内容转换成字符串String request = new String(datagramPacket.getData(),0,datagramPacket.getLength());//2.根据请求处理响应String torequest = prcess(request);//3.将响应返回给客户端//3.1 将响应构造成数据报,但是UDP是无连接,所以需要将客户端的信息保存到数据报中DatagramPacket datagramPacket1 = new DatagramPacket(torequest.getBytes(),torequest.getBytes().length,datagramPacket.getSocketAddress());datagramSocket.send(datagramPacket1);}private String prcess(String request) {return request;}}

客户端实现思路:

客户端不用知道自己的端口,需要知道服务器的IP和端口。再将输入的内容打包成一个数据报,发送给服务器,再将响应的数据报解析成字符串,最后打印。

public class Cilent {private String ServerIP;private int ServerPort;private DatagramSocket datagramSocket = null;public Cilent(String serverIP, int serverPort) throws SocketException {ServerIP = serverIP;ServerPort = serverPort;datagramSocket = new DatagramSocket();}public void start() throws IOException {Scanner scanner = new Scanner(System.in);//1. 从控制台上读取请求String re = scanner.next();//2. 将请求发送给服务器DatagramPacket datagramPacket = new DatagramPacket(re.getBytes(),re.getBytes().length,InetAddress.getByName(ServerIP),ServerPort);datagramSocket.send(datagramPacket);//3. 读取服务器返回的响应DatagramPacket datagramPacket1 = new DatagramPacket(new byte[4096],4096);datagramSocket.receive(datagramPacket1);String s = new String(datagramPacket1.getData(),0,datagramPacket1.getLength());//4. 将响应显示到控制台System.out.println(s);}
}

客户端和服务器代码的区别:

1.客户端不用知道自己的端口,操作系统会随机分配一个空闲的端口,是因为客户端是发送请求的一方,要知道服务器的IP和端口才能发送,而服务器只要知道自己的端口,返回响应时接收的数据报里有客户端的信息。

 TCP协议

两个核心的类:ServerSocket和Socket。

ServerSocket:

打开它相当于打开一个socket文件,但是它不是负责“发送”“接收”,而是建立TCP连接,这个对象是专门给服务器使用的。

Socket:

打开它相当于打开socket文件,这个类双方都会使用,用来发送接收数据。

使用TCP协议编写一个简单网络程序

客户端:

1.用户从控制台输入

2.将请求发送给服务器

3.接送服务器返回的响应

4.将响应返回到控制台

服务器:

1.接收客户端的请求

2.根据请求次数处理响应

3.返回响应

编写服务器思路:TCP协议是要进行连接的,所以不可以一上来就进行读写数据,要先进行从内核中将连接拿取,连接后就会返回一个Socket文件,之后就是对socket文件进行处理。

要拿到Socket中的流对象进行读写操作,读出数据后就要进行处理相应(这里读数据可以用scanner从流对象中进行读取,当读到的数据为空时就返回跳出循环,断开连接),处理完成后就要通过PrintWriter返回响应。

public class server {private ServerSocket serverSocket = null;public server(int port) throws IOException {this.serverSocket = new ServerSocket(port);}private void start() throws IOException {System.out.println("服务器启动");while(true){//通过accent建立连接//ServerSocket是建立连接,Socket负责进行数据通信,后面的都是针对Socket进行数据的传输//Serversocket 和 Socket 之间的关系类似前者将你介绍到总部的销售,后者是给你介绍的销售Socket socket =  serverSocket.accept();processa(socket);}}private void processa(Socket socket) {try (InputStream inputStream = socket.getInputStream(); OutputStream outputStream = socket.getOutputStream()){Scanner scanner = new Scanner(inputStream);PrintWriter printWriter = new PrintWriter(outputStream);while (true){//循环处理,一个客户端可能和服务器有多轮响应//读取并解析响应if(!scanner.hasNext()){break;}String request = scanner.next();//根据请求计算响应String response = process(request);//返回响应printWriter.print(response);}}catch (IOException e){e.printStackTrace();}}private String process(String response){return response;}
}

注意事项:一个端口被同时使用于TCP和UDP协议是不会发生冲突的。

编写客户端思路:

TCP是有连接,所以要一上来就进行连接,然后就是进行发送和接收,但是发送时要注意有缓冲区(buffer),发送的printin其实并没有进行发送,而是把数据填写到缓冲区中,这是因为CPU读写内存比外设要快的多,所以在读写入网卡时就会等缓冲区的达到一定时,才会打包发送,但是可以通过flush进行提前唤醒。

public class EcohCilent {public Socket socket = null;public EcohCilent(String serverip, int serverPort) throws IOException {//有连接,先上来要建立连接,是由操作系统进行操作的,但是我们要指定服务器的端口和ipsocket = new Socket(serverip, serverPort);}public void start() {Scanner scanner = new Scanner(System.in);System.out.println("客户端启动!");try (InputStream inputStream = socket.getInputStream(); OutputStream outputStream = socket.getOutputStream()) {//接收服务器时创建的scanned,用于读取服务器返回的内容while (true) {Scanner scanner1 = new Scanner(inputStream);PrintWriter writer = new PrintWriter(outputStream);//输入请求System.out.println(">");String request = scanner.next();//进行打包发送到服务器writer.println(request);writer.flush();//接收返回的请求if (!scanner1.hasNext()) {System.out.println("服务器断开连接");break;}String rerequest = scanner1.next();System.out.println(rerequest);}}catch(IOException e){e.printStackTrace();}}

注意事项:

1.在TCP客户端中要频繁创建Socket,可能就会导致文件资源泄漏,所以要及时关闭。而UDP中不用进行关闭是因为它不需要频繁创建socket文件。

2.在TCP中当有多个客户端发送请求时就会出现问题。这是因为上面的代码有两层循环,当进入第二层循环时会发生阻塞,这是就要通过线程的方式处理。

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

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

相关文章

【电机】定点线性映射

这是一个定点数线性映射的问题,通常用于将浮点型的物理量(如速度、位置、扭矩)转换为嵌入式系统中使用的整型数据格式,便于通过 CAN 总线或其它通信协议发送给电机控制器。 我们来逐步解析这个过程,并以“速度”为例说…

Spring Cloud 微服务(远程调用与熔断机制深度解析)

📌 摘要 在微服务架构中,服务之间的远程调用是构建分布式系统的核心环节。然而,随着服务数量的增加和网络复杂度的提升,调用失败、延迟高、异常等问题变得越来越频繁。 为此,Spring Cloud 提供了强大的远程调用组件 …

electron-vite 抽离config.js

1、将config.js 放到resources下的config目录下 module.exports {url: http://192.168.1.17:8000,wsUrl: ws://192.168.1.17:8000, }2、在preload.js 暴露读取API src/preload/index.js(或你的preload入口) const fs require(fs); const path require(path);function getCo…

MySQL Undo Log 深度解析:事务回滚与MVCC的核心功臣

引言 作为MySQL的“数据后悔药”和“历史版本档案馆”,Undo Log(回滚日志)在事务处理和并发控制中扮演着至关重要的角色。今天咱们就从底层原理出发,结合实际场景,把Undo Log的“里里外外”说个明白! 一、…

gin如何返回html

✅ 方法一&#xff1a;直接返回 HTML 字符串 这种方式适合简单场景&#xff0c;比如返回一段固定的 HTML 内容。 package mainimport "github.com/gin-gonic/gin"func main() {r : gin.Default()r.GET("/html", func(c *gin.Context) {htmlContent : <…

Insulation score算法解读

Insulation score&#xff08;IS&#xff09;&#xff0c;俗称绝缘分数&#xff0c;用于计算识别三维基因组中的拓扑关联结构域TAD。 首次提出是在&#xff1a; 1&#xff0c;概念 为染色体上的基因组区间分配‘绝缘评分’的方法。该评分用于衡量跨越每个区间的所有相互作用的…

电脑系统重装有什么用?

一、解决系统软件问题 1、修复系统崩溃与错误 系统出现频繁蓝屏、死机、启动失败或程序运行异常&#xff08;如驱动冲突、系统文件损坏&#xff09; 2、清除恶意软件与病毒 电脑中病毒或恶意软件难以通过杀毒软件彻底清除 二、优化系统性能 1、清理冗余文件与设置 长时间…

js随机生成一个颜色

在 JavaScript 中&#xff0c;随机生成颜色有多种方式&#xff0c;以下是最常见的几种实现方法&#xff1a; 方法1&#xff1a;生成随机十六进制颜色&#xff08;如 #FFFFFF&#xff09; 这是最常见的方式&#xff0c;生成格式为 #RRGGBB 的颜色字符串&#xff1a; function…

运维打铁: 服务器防火墙策略配置与管理

文章目录 思维导图一、防火墙基础1. 防火墙概念2. 常见防火墙类型3. 防火墙工作原理 二、策略配置1. 规则制定原则2. 端口与服务开放Linux 系统&#xff08;以 iptables 为例&#xff09;Windows 系统&#xff08;以 Windows 防火墙为例&#xff09; 3. IP 地址过滤允许特定 IP…

locate 命令更新机制详解

文章目录 **一、定时更新的实现载体&#xff1a;crontab 任务****二、定时任务的配置逻辑****三、更新触发的额外机制****四、更新流程的性能优化****五、常见问题与解决方案****总结** 一、定时更新的实现载体&#xff1a;crontab 任务 Linux 系统通常通过 crontab 定时任务 …

docker部署nacos【单机模式使用mysql,使用.env配置】(更新:2025/7/1~)

视频 我的个人视频&#xff0c;有详细步骤 使用docker部署nacos_哔哩哔哩_bilibili 环境 虚拟机&#xff1a;VM&#xff0c;CentOS7 远程连接工具&#xff1a;MobaXterm 使用工具 随机生成字符串&#xff1a; 随机字符串生成器 | 菜鸟工具 Base64编码&#xff1a; B…

如何安全地清除笔式驱动器

您是否正在寻找安全清除笔式驱动器的方法&#xff1f;如果是的话&#xff0c;您可以从本文中得到4个有效的解决方案。无论您准备出售还是捐赠您的笔式驱动器&#xff0c;您都可以轻松清空笔式驱动器。虽然简单的删除似乎就足够了&#xff0c;但残留的数据通常可以恢复。因此&am…

信息新技术

目录 分布式处理基础 一、基础概念 二、通信与网络 三、分布式协调与一致性 四、分布式存储与数据库 五、分布式计算框架 六、容错与高可用 七、负载均衡与调度 八、安全与监控 九、常见分布式系统设计模式 十、典型系统与工具学习 区块链 区块链的核心技术 物联…

创客匠人解析创始人 IP 定位:从专业度到用户心智的占领之道

在知识付费领域&#xff0c;创始人 IP 的定位往往决定了商业变现的天花板。创客匠人通过服务 5 万 知识博主的实践经验&#xff0c;揭示了一个核心逻辑&#xff1a;定位的本质不是简单的标签设定&#xff0c;而是通过持续提升专业度&#xff0c;以实际成果占领用户心智。这一过…

详解Kafka如何保证消息可靠性

Kafka 通过多个环节的精心设计和配置&#xff0c;能够提供高可靠的消息传递保证&#xff0c;最大限度地减少消息丢失的可能性。这需要生产者、Broker 和消费者三方的协同配置才能实现端到端的不丢失。以下是关键机制&#xff1a; 一、核心原则&#xff1a;副本机制 (Replicati…

华为云Flexus+DeepSeek征文 | Word办公软件接入华为云ModelArts Studio大模型,实现AI智能办公

前言 在数字化办公时代&#xff0c;人工智能技术正深刻改变着传统办公软件的使用体验和功能边界。将 Word 办公软件与华为云 ModelArts Studio 大模型进行深度融合&#xff0c;借助 AI 的强大能力实现智能化优化&#xff0c;不仅能大幅提升办公效率&#xff0c;还能为用户带来…

基于开源AI大模型AI智能名片S2B2C商城小程序的流量转化与价值沉淀研究

摘要&#xff1a;在数字化商业生态中&#xff0c;公域流量转化已成为企业竞争的核心战场。本文以开源AI大模型AI智能名片S2B2C商城小程序为研究对象&#xff0c;结合服装、健康食品、快时尚等行业的实践案例&#xff0c;系统分析其通过技术赋能实现精准获客、用户留存与商业闭环…

创客匠人拆解知识变现困局:创始人 IP 打造的底层逻辑与实践路径

在知识付费行业竞争愈发激烈的当下&#xff0c;许多内容创作者面临 “流量增长停滞、变现效率低下” 的困境。创客匠人通过对 5 万 知识博主的服务经验&#xff0c;总结出创始人 IP 打造与知识变现的底层逻辑 —— 其核心在于将 “个人影响力” 转化为 “商业闭环”&#xff0…

LabVIEW远程面板交互控制

基于LabVIEW 远程面板&#xff08;Remote Panel&#xff09;技术&#xff0c;实现服务器端 VI 与客户端的远程交互控制&#xff0c;涵盖服务器配置、客户端连接请求、VI 执行状态监测及控制权交接等流程&#xff0c;支持跨 LabVIEW 实例&#xff08;可跨设备&#xff09;的远程…

S7-1200 CPU 与 CP343-1 S7 通信(S7-1200 作为服务器)

S7-1200 CPU 与 CP343-1 S7 通信&#xff08;S7-1200 作为服务器&#xff09; S7-1200 CPU 与 CP343-1 之间的以太网通信通过 S7 通信来实现。当 CP343-1&#xff08;至少标准版&#xff09;作为客户端&#xff0c;S7-1200 作为服务器&#xff0c;需在客户端单边组态连接和编程…