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分努力,达到了冲刺满分的实力时,得个优秀的成绩也并不意外。 …...

通过Wrangler CLI在worker中创建数据库和表
官方使用文档:Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后,会在本地和远程创建数据库: npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库: 现在,您的Cloudfla…...

《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)
CSI-2 协议详细解析 (一) 1. CSI-2层定义(CSI-2 Layer Definitions) 分层结构 :CSI-2协议分为6层: 物理层(PHY Layer) : 定义电气特性、时钟机制和传输介质(导线&#…...
渲染学进阶内容——模型
最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...
unix/linux,sudo,其发展历程详细时间线、由来、历史背景
sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...
鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/
使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题:docker pull 失败 网络不同,需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...

多种风格导航菜单 HTML 实现(附源码)
下面我将为您展示 6 种不同风格的导航菜单实现,每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列,以便知晓哪些列包含有价值的数据,…...

力扣热题100 k个一组反转链表题解
题目: 代码: func reverseKGroup(head *ListNode, k int) *ListNode {cur : headfor i : 0; i < k; i {if cur nil {return head}cur cur.Next}newHead : reverse(head, cur)head.Next reverseKGroup(cur, k)return newHead }func reverse(start, end *ListNode) *ListN…...

恶补电源:1.电桥
一、元器件的选择 搜索并选择电桥,再multisim中选择FWB,就有各种型号的电桥: 电桥是用来干嘛的呢? 它是一个由四个二极管搭成的“桥梁”形状的电路,用来把交流电(AC)变成直流电(DC)。…...

Mysql故障排插与环境优化
前置知识点 最上层是一些客户端和连接服务,包含本 sock 通信和大多数jiyukehuduan/服务端工具实现的TCP/IP通信。主要完成一些简介处理、授权认证、及相关的安全方案等。在该层上引入了线程池的概念,为通过安全认证接入的客户端提供线程。同样在该层上可…...