04_网络编程
网络编程
什么是网络编程
可以让设备中的程序与网络上其他设备中的程序进行数据交互(实现网络通信的)
java.net.* 包下提供了网络编程的解决方案
通信的基本架构
- CS 架构(Client 客户端 / Server 服务端)
- BS 架构(Browser 客户端 / Server 服务端)
网络通信三要素
- IP 地址
- 端口号
- 协议
IP 地址
import java.net.InetAddress;public class Test {public static void main(String[] args) throws Exception {// 1. 获取本机IP地址对象InetAddress ip1 = InetAddress.getLocalHost();System.out.println(ip1.getHostName()); // TOMATOSystem.out.println(ip1.getHostAddress()); // 10.233.86.87// 2. 获取指定IP或者域名的IP地址对象InetAddress ip2 = InetAddress.getByName("www.baidu.com");System.out.println(ip2.getHostName()); // www.baidu.comSystem.out.println(ip2.getHostAddress()); // 120.232.145.185// 3. 判断6000毫秒内,是否能够连通百度System.out.println(ip2.isReachable(6000)); // true}
}
端口号
- 标记正在计算机设备上运行的应用程序,被规定为一个16位的二进制,范围是 0 ~ 65535
通信协议
- 网络上通信的设备,事先规定的连接规则,以及传输数据的规则被称为网络通信协议
- UDP(User Datagram Protocol):用户数据报协议;
- TCP(Transmission Control Protocol):传输控制协议
UDP
- 特点:无连接,不可靠通信
快速入门
// 客户端import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;public class Client {public static void main(String[] args) throws Exception {// 1. 创建客户端对象DatagramSocket socket = new DatagramSocket();// 2. 创建数据包对象封装要发出去的数据/*public DatagramPacket(byte buf[], int length, SocketAddress address) {参数一 : 封装要发出去的数据参数二 : 发送出去的数据大小(字节个数)参数三 : 服务端的IP地址(找到服务端主机)参数四 : 服务端的端口}*/byte[] bytes = "我是客户端".getBytes();DatagramPacket packet = new DatagramPacket(bytes, bytes.length,InetAddress.getLocalHost(), 6666);// 3. 开始正式发送这个数据包的数据出来了socket.send(packet);System.out.println("客户端数据发送完毕!");// 4. 关闭连接,释放其所占用的网卡资源socket.close();}
}
// 服务端import java.net.DatagramPacket;
import java.net.DatagramSocket;public class Server {public static void main(String[] args) throws Exception {System.out.println("---服务端启动---");// 1. 创建一个服务端对象DatagramSocket socket = new DatagramSocket(6666); // 参数:端口号// 2. 创建一个数据包对象,用于接收数据byte[] buffer = new byte[1024 * 64]; // 64KBDatagramPacket packet = new DatagramPacket(buffer, buffer.length); // 参数:// 3. 正式使用数据包来接收客户端发来的数据socket.receive(packet);// 客户端ipSystem.out.println(packet.getAddress().getHostAddress());System.out.println(packet.getPort());// 4. 从字节数组中,把接收到的数据直接打印出来// 接收多少就倒出多少// 获取本次数据包接收了多少数据int len = packet.getLength();String res = new String(buffer, 0, len);System.out.println(res);}
}
多发多收
// 客户端import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Scanner;public class Client {public static void main(String[] args) throws Exception {// 1. 创建客户端对象DatagramSocket socket = new DatagramSocket();// 2. 创建数据包对象封装要发出去的数据/*public DatagramPacket(byte buf[], int length, SocketAddress address) {参数一 : 封装要发出去的数据参数二 : 发送出去的数据大小(字节个数)参数三 : 服务端的IP地址(找到服务端主机)参数四 : 服务端的端口}*/Scanner sc = new Scanner(System.in);while (true) {System.out.println("请输入>>> ");String msg = sc.nextLine();// 如果用户输入exit命令,就执行退出if ("exit".equals(msg)) {System.out.println("欢迎再来!");socket.close(); // 4. 关闭连接,释放其所占用的网卡资源break;}byte[] bytes = msg.getBytes();DatagramPacket packet = new DatagramPacket(bytes, bytes.length,InetAddress.getLocalHost(), 6666);// 3. 开始正式发送这个数据包的数据出来了socket.send(packet);System.out.println("客户端数据发送完毕!");}}
}
// 服务端import java.net.DatagramPacket;
import java.net.DatagramSocket;public class Server {public static void main(String[] args) throws Exception {System.out.println("---服务端启动---");// 1. 创建一个服务端对象DatagramSocket socket = new DatagramSocket(6666); // 参数:端口号// 2. 创建一个数据包对象,用于接收数据byte[] buffer = new byte[1024 * 64]; // 64KBDatagramPacket packet = new DatagramPacket(buffer, buffer.length); // 参数:while (true) {// 3. 正式使用数据包来接收客户端发来的数据socket.receive(packet);// 客户端ipSystem.out.println(packet.getAddress().getHostAddress());System.out.println(packet.getPort());// 4. 从字节数组中,把接收到的数据直接打印出来// 接收多少就倒出多少// 获取本次数据包接收了多少数据int len = packet.getLength();String res = new String(buffer, 0, len);System.out.println(res);System.out.println("-------------------");}}
}
TCP
- 特点:面向连接,可靠通信
快速入门
// 客户端import java.io.DataOutputStream;
import java.io.OutputStream;
import java.net.Socket;public class Client {public static void main(String[] args) throws Exception {// 1. 创建 Socket 对象,并同时请求与服务器程序的连接Socket socket = new Socket("127.0.0.1", 8888);// 2. 从 socket 通信管道中得到一个字节输出流,用来发数据给服务端程序OutputStream os = socket.getOutputStream();// 3. 把低级的字节输出流包装成数据输出流DataOutputStream dos = new DataOutputStream(os);// 4. 开始写数据出去了dos.writeUTF("我们还是好朋友,对吧?");dos.close(); // 关闭数据输出流管道socket.close(); // 释放连接资源}
}
// 服务端import java.io.DataInputStream;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;public class Server {public static void main(String[] args) throws Exception {System.out.println("---服务端启动---");// 1. 创建 ServerSocket 的对象,同时为服务端注册端口ServerSocket serverSocket = new ServerSocket(8888);// 2. 使用 serverSocket 对象,调用一个 accept 方法,等待客户端的连接请求Socket socket = serverSocket.accept();// 3. 从 socket 通信管道中得到一个字节输入流InputStream is = socket.getInputStream();// 4. 把原始的字节输入流包装成数据输入流DataInputStream dis = new DataInputStream(is);// 5. 使用数据输入流读取客户端发送过来的消息String res = dis.readUTF();System.out.println(res);// 输出客户端的IP地址System.out.println(socket.getRemoteSocketAddress());dis.close();socket.close();}
}
多发多收
// 客户端package login;import java.io.DataOutputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Scanner;public class Client {public static void main(String[] args) throws Exception {// 1. 创建 Socket 对象,并同时请求与服务器程序的连接Socket socket = new Socket("127.0.0.1", 8888);// 2. 从 socket 通信管道中得到一个字节输出流,用来发数据给服务端程序OutputStream os = socket.getOutputStream();// 3. 把低级的字节输出流包装成数据输出流DataOutputStream dos = new DataOutputStream(os);Scanner sc = new Scanner(System.in);while (true) {System.out.println("请输入>>> ");String msg = sc.nextLine();if("exit".equals(msg)){System.out.println("欢迎再来!");dos.close(); // 关闭数据输出流管道socket.close(); // 释放连接资源break;}// 4. 开始写数据出去了dos.writeUTF(msg);dos.flush();}}
}
// 服务端package login;import java.io.DataInputStream;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;public class Server {public static void main(String[] args) throws Exception {System.out.println("---服务端启动---");// 1. 创建 ServerSocket 的对象,同时为服务端注册端口ServerSocket serverSocket = new ServerSocket(8888);// 2. 使用 serverSocket 对象,调用一个 accept 方法,等待客户端的连接请求Socket socket = serverSocket.accept();// 3. 从 socket 通信管道中得到一个字节输入流InputStream is = socket.getInputStream();// 4. 把原始的字节输入流包装成数据输入流DataInputStream dis = new DataInputStream(is);while (true) {try {// 5. 使用数据输入流读取客户端发送过来的消息String res = dis.readUTF();System.out.println(res);} catch (Exception e) {System.out.println(socket.getRemoteSocketAddress()+"断开了连接");;socket.close();break;}}}
}
多个客户端同时使用服务端
// 客户端import java.io.DataOutputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Scanner;public class Client {public static void main(String[] args) throws Exception {// 1. 创建 Socket 对象,并同时请求与服务器程序的连接Socket socket = new Socket("127.0.0.1", 8888);// 2. 从 socket 通信管道中得到一个字节输出流,用来发数据给服务端程序OutputStream os = socket.getOutputStream();// 3. 把低级的字节输出流包装成数据输出流DataOutputStream dos = new DataOutputStream(os);Scanner sc = new Scanner(System.in);while (true) {System.out.println("请输入>>> ");String msg = sc.nextLine();if("exit".equals(msg)){System.out.println("欢迎再来!");dos.close(); // 关闭数据输出流管道socket.close(); // 释放连接资源break;}// 4. 开始写数据出去了dos.writeUTF(msg);dos.flush();}}
}
// 服务端import java.io.DataInputStream;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;public class Server {public static void main(String[] args) throws Exception {System.out.println("---服务端启动---");// 创建 ServerSocket 的对象,同时为服务端注册端口ServerSocket serverSocket = new ServerSocket(8888);while (true) {// 使用 serverSocket 对象,调用一个 accept 方法,等待客户端的连接请求Socket socket = serverSocket.accept();System.out.println(socket.getRemoteSocketAddress() + "连接到了服务端");// 使用一个独立的线程,把当前的 socket 对象交给它负责处理new ServerReaderThread(socket).start();}}
}class ServerReaderThread extends Thread {private Socket socket;public ServerReaderThread(Socket socket) {this.socket = socket;}@Overridepublic void run() {try {// 从 socket 通信管道中得到一个字节输入流InputStream is = socket.getInputStream();// 把原始的字节输入流包装成数据输入流DataInputStream dis = new DataInputStream(is);while (true) {try {// 使用数据输入流读取客户端发送过来的消息String res = dis.readUTF();System.out.println(res);} catch (Exception e) {System.out.println(socket.getRemoteSocketAddress() + "断开了连接");dis.close(); // 关闭流管道socket.close(); // 关闭连接管道break;}}} catch (Exception e) {e.printStackTrace();}}
}
相关文章:
04_网络编程
网络编程 什么是网络编程 可以让设备中的程序与网络上其他设备中的程序进行数据交互(实现网络通信的) java.net.* 包下提供了网络编程的解决方案 通信的基本架构 CS 架构(Client 客户端 / Server 服务端)BS 架构(…...
【五分钟】熟练使用numpy.cumsum()函数(干货!!!)
引言 numpy.cumsum()函数用于计算输入数组的累积和。当输入是多维数组时,numpy.cumsum()函数可以沿着指定轴计算累积和。 计算一维数组的累计和 代码如下: # 计算一维数组的累计和 tmp_array np.ones((4,), dtypenp.uint8) # [1, 1, 1, 1] print(&…...
由11月27日滴滴崩溃到近两个月国内互联网产品接二连三崩溃引发的感想
文章目录 知乎文分析微信聊天截图微信公众号 滴滴技术 发文k8s 官方文档滴滴官方微博账号 近两个月国内互联网产品“崩溃”事件2023-10-23 语雀崩溃2023-11-12 阿里云崩溃2023-11-27 滴滴崩溃2023-12-03 腾讯视频崩溃总结 我的感想 知乎文分析 最近连续加班,打车较…...
Python按要求从多个txt文本中提取指定数据
基本想法 遍历文件夹并从中找到文件名称符合我们需求的多个.txt格式文本文件,并从每一个文本文件中,找到我们需要的指定数据,最后得到所有文本文件中我们需要的数据的集合 举例 如现有名为file一个文件夹,里面含有大量的.txt格…...
DFT新手教程:VASP中ISIF取值设置
新手初学VASP计算时首先接触到的就是结构优化的计算任务。 在结构优化中,INCAR中的关键参数包括 IBRION ,NSW,ISIF,EDIFF和EDIFFG 各个参数均可在vaspwiki查到可设置的参数以及该参数所具有的设置的含义。 https://www.vasp.at/…...
pytest自动化框架之allure测试报告的用例描述设置
allure测试报告的用例描述相关方法;如下图 allure标记用例级别severity 在做自动化测试的过程中,测试用例越来越多的时候,如果执行一轮测试发现了几个测试不通过,我们也希望能快速统计出缺陷的等级。 pytest结合allure框架可以对…...
在编程中遇到的问题总结
IDEA空包粘黏问题 创建好目录以后会发现idea自动将空包合并在一起了,而且点击设置里面也没有Compact Middle Package Compact Middle Package如果不在设置的主面板上,则点击Tree Appearance,会发现Compact Middle Package在Tree Appearance里…...
【数据库设计和SQL基础语法】--SQL语言概述--SQL的基本结构和语法规则(二)
一、数据控制语言(DCL) 1.1 授权(GRANT) 数据控制语言(DCL)是SQL的一个子集,用于控制数据库中的数据访问和权限。GRANT语句是DCL中的一种,用于向用户或角色授予特定的数据库操作权…...
easyexcel多级表头导出各级设置样式(继承HorizontalCellStyleStrategy实现)
easyexcel多级表头导出各级设置样式(继承HorizontalCellStyleStrategy实现) package com.example.wxmessage.entity;import com.alibaba.excel.metadata.data.WriteCellData; import com.alibaba.excel.write.handler.context.CellWriteHandlerContext;…...
QMLfor python pyside6
QML QML是一种用于创建用户界面的声明性语言,它是Qt生态系统中的一部分。QML使用JavaScript语言和其独特的语法来定义用户界面组件,使得开发人员可以轻松地创建现代化、漂亮而又响应迅速的应用程序。 QML是基于QtQuick技术构建的,QtQuick是…...
几何教学工具 Sketchpad几何画板 mac软件特色
Sketchpad几何画板 for Mac是一款适用于macOS系统的几何教学工具,用户可以在其画板上进行各种几何图形的绘制、演示,帮助教师了解学生的思路和对概念的掌握程度。此外,Sketchpad更深层次的功能则是可以用来进行几何交流、研究和讨论ÿ…...
华清远见嵌入式学习——C++——作业5
作业要求: 代码: #include <iostream>using namespace std;//沙发 类 class Sofa { private:string sitting; //是否可坐double *cost; //花费 public://无参构造函数Sofa(){}//有参构造函数Sofa(string s,double c):sitting(s),cost(new double(…...
Java中的类与类之间的关系
1、Java中类与类之间的关系 依赖(Dependency):一个类依赖于另一个类的定义。这种关系通常通过在一个类的方法中创建另一个类的实例来实现。依赖关系是类与类之间最基本的关系之一。关联(Association):关联…...
全新仿某度文库网站源码/在线文库源码/文档分享平台网站源码/仿某度文库PHP源码
源码简介: 全新仿某度文库网站源码/在线文库源码,是以phpMySQL开发的,它是仿某度文库PHP源码。有功能免费文库网站 文档分享平台 实现文档上传下载及在线预览。 仿百度文库是一个以phpMySQL进行开发的免费文库网站源码。仿某度文库实现文档…...
HTTPS的安全问题及应对方案
HTTPS是一种在网络通信中广泛使用的安全协议,通过使用SSL/TLS加密来保护数据的传输。然而,即使在使用了HTTPS的情况下,仍然存在一些潜在的安全问题。本文将深入探讨HTTPS的安全问题,并提供一些有效的应对策略,以确保数…...
TensorRT-LLM保姆级教程(一)-快速入门
随着大模型的爆火,投入到生产环境的模型参数量规模也变得越来越大(从数十亿参数到千亿参数规模),从而导致大模型的推理成本急剧增加。因此,市面上也出现了很多的推理框架,用于降低模型推理延迟以及提升模型…...
使用Redis构建简易社交网站(3)-状态与信息流
目的 本文目的:实现获取主页时间线和状态推送功能。(完整代码附在文章末尾) 相关知识 在我上一篇文章 《使用Redis构建简易社交网站(2)-处理用户关系》中提到了实现用户关注和取消关注功能。 那这篇文章将教会你掌握:1&#x…...
Python,非二进制的霍夫曼编码
一般来说,霍夫曼编码是二进制的,但是非二进制的也可以。本文中,通过修改N,可以得到任意进制的霍夫曼编码。 非二进制编码的作用:例如,设计九键输入法,希望根据拼音的概率来编码,常用…...
详解—[C++数据结构]—红黑树
目录 一、红黑树的概念 编辑二、红黑树的性质 三、红黑树节点的定义 四、红黑树结构 五、红黑树的插入操作 5.1. 按照二叉搜索的树规则插入新节点 5.2、检测新节点插入后,红黑树的性质是否造到破坏 情况一: cur为红,p为红,g为黑&…...
甘草书店记:6# 2023年10月31日 星期二 「梦想从来不是一夜之间实现的」
甘草书店 今天收到甘草书店第二版装修设计平面图,与理想空间越来越近。 于我而言,每一次世俗意义上所谓的成功都不如文艺作品中表现的那样让人欢腾雀跃。当你用尽120分努力,达到了冲刺满分的实力时,得个优秀的成绩也并不意外。 …...
仿真模型中硅胶减震器的特征频率与谐振频率的受力分析
COMSOL仿真模型硅胶减震器减振器特征频率谐振频率受力分析仿真模型最近在研究硅胶减震器的特性,发现用COMSOL来仿真这东西还挺有意思的。硅胶减震器嘛,主要就是用来减振的,比如在一些精密仪器或者机械设备上,防止振动对设备造成损…...
LyricsX:突破平台限制,重构macOS歌词体验的开源解决方案
LyricsX:突破平台限制,重构macOS歌词体验的开源解决方案 【免费下载链接】LyricsX 🎶 Ultimate lyrics app for macOS. 项目地址: https://gitcode.com/gh_mirrors/ly/LyricsX 在流媒体音乐蓬勃发展的今天,音乐爱好者们却常…...
Qwen3.5小尺寸模型开源,9B碾压GPT开源版,消费级显卡就能跑
AI圈又出大新闻了✨ 阿里通义千问3.5系列小尺寸模型正式亮相,直接打破“小模型能力弱”的固有认知,甚至实现了“以小胜大”的逆袭,本地部署门槛直接拉到平民级! 先上核心干货——这次千问3.5一口气推出了4款小尺寸模型,…...
ccmusic-database新手教程:Gradio输出组件定制——增强Top5结果可读性技巧
ccmusic-database新手教程:Gradio输出组件定制——增强Top5结果可读性技巧 1. 项目简介与背景 ccmusic-database是一个基于深度学习的音乐流派分类系统,它能够自动识别音频文件所属的音乐流派。这个系统在计算机视觉预训练模型VGG19_BN的基础上进行微调…...
Science重磅指南:如何打造高影响力论文摘要?附Abstract写作黄金法则!
1. 科学论文摘要的黄金结构 写论文摘要就像给陌生人讲一个精彩的故事——要在短短200字内让人眼前一亮。我在Nature和Science上发过几篇论文,也审过上百篇投稿,发现顶级期刊的摘要其实有套"万能公式"。这个公式的核心是把摘要拆解成7个关键部分…...
告别复杂配置!5分钟掌握OCAT:OpenCore图形化配置神器
告别复杂配置!5分钟掌握OCAT:OpenCore图形化配置神器 【免费下载链接】OCAuxiliaryTools Cross-platform GUI management tools for OpenCore(OCAT) 项目地址: https://gitcode.com/gh_mirrors/oc/OCAuxiliaryTools 如果你…...
本地Cookie导出终极指南:Get cookies.txt LOCALLY 安全使用教程
本地Cookie导出终极指南:Get cookies.txt LOCALLY 安全使用教程 【免费下载链接】Get-cookies.txt-LOCALLY Get cookies.txt, NEVER send information outside. 项目地址: https://gitcode.com/gh_mirrors/ge/Get-cookies.txt-LOCALLY 你是否曾担心浏览器Coo…...
RPA工程化实践:三种核心设计模式让复杂流程优雅可控
一、为什么RPA需要设计模式? 在回答这个问题前,我们先看一个典型的复杂RPA场景:企业财务自动化需要从多个系统获取数据(ERP、CRM、银行),经过清洗、验证、转换,然后生成报表并上传至OA系统&…...
变压器绕组类型 | 高频变压器绕制要点
注:本文为 “变压器绕制” 相关合辑。 英文引文,机翻未校。 如有内容异常,请看原文。 图片清晰度受引文原图所限。 变压器绕组类型:圆筒式、螺旋式、交叉式与饼式绕组 Types of Transformer Windings: Cylindrical, Helical, Cro…...
告别手动编译:用Conda在Ubuntu 20.04上一键安装与管理SUMO交通仿真环境
告别手动编译:用Conda在Ubuntu 20.04上一键安装与管理SUMO交通仿真环境 在交通工程和智能驾驶研究领域,SUMO(Simulation of Urban MObility)作为开源的微观交通仿真工具,正被越来越多的研究者和开发者采用。然而&#…...
