javaSE————网络编程套接字

网络编程套接字~~~~~

好久没更新啦,蓝桥杯爆掉了,从今天开始爆更嗷;

1,网络编程基础

为啥要有网络编程呢,我们进行网络通信就是为了获取丰富的网络资源,说实话真的很神奇,想想我们躺在床上,通过网络,访问到世界上成千上万的人做好的网络资源,我们甚至能看到一辈子都看不到的景色,这些资源本质上都是二进制资源或者是文本资源,我们通过网络可以让很多人来访问,这个就是网络编程,当年的网络就是个看报的,谁能想到发展到这样呢?

网络编程的概念:网络上的主机,通过不同的进程,以编程的方式实现网络通信;

同一个主机下的不同进程实现网络通信也是网络编程;

网络编程的基本概念:

接收端:数据接收端进程,目标主机;

发送端:数据发送端进程,源主机;

收发端:发送接收两端;

请求:请求数据的发送;

响应:响应数据的发送;

就像我们去餐厅点一份蛋炒饭就是请求,厨师给我们拿来蛋炒饭就是回应;

服务端:提供服务的一方,返回服务资源;

客户端:获取服务的一方;


2,Socket套接字

Socket就是套接字,啥是套接字,这名起的,Socket套接字是由系统提供用于网络通信的技术,是基于TCP/IP协议的网络通信的基本单元,基于Socket套接字的网络程序开发就是网络编程;

Socket套接字主要针对传输层协议划分为三类:

我们这里就学两个核心协议

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

2,UDP,无连接,不可靠传输,面向数据报,全双工;

这里的有连接和无连接都是抽象的概念,虚拟上的连接;

TCP协议保存了对端的信息,A和B通信,A和B先建立连接,A保存了B的信息,B也保存了A的信息,他们彼此都知道谁与自己建立的连接,而UDP不保存对方的信息;

可靠传输和不可靠传输是什么呢?

网络上,数据的传输是会发生丢包的情况的,可能会受到外界的干扰,那么可靠传输就能避免这样的丢包吗,事实上是不能的,可靠传输只是保证尽可能提高传输成功的概率,如果出现了丢包,也能感知到,不可靠传输的话就是把数据发送之后就不管了,那么这样的话我们就使用可靠传输就好了呀,还要UDP干嘛呢,凡是必有代价,UDP的话速度会更快;

面向字节流和面向数据报呢?

面向字节流:读写数据的时候,以字节为单位;

面向数据报:读写数据的时候,以一个数据报为单位;

全双工和半双工呢?

全双工:一个通信联络,能读也能写;

半双工:只支持单向通信,要么读,要么写;

我们使用Socket api来进行网络编程,我们之前提到计算机中的“文件”有狭义和广义的概念,硬件设备可以抽象成文件,统一管理;电脑上的网卡就是Socket文件;


3,UDP数据报套接字编程

我们先来介绍UDP需要的API:

DatagramSocket

UDP的Socket用于接收和发送UDP数据报;

构造方法:

方法签名方法说明
DatagramSocket()创建一个UDP数据报套接字的Socket,绑定到本机任意一个端口,一般用于客户端
DatagramSocket(int port)创建一个UDP数据报套接字的Socket,绑定到本机指定的端口,一般用于服务端

方法:

方法签名方法说明
void receive(DatagramPacket p)从此套接字接收数据报,如果没有收到数据报就会阻塞等待;
void send(DatagramPacket p)从此套接字发送数据报,不会阻塞等待,直接发送;
void close()关闭此数据报套接字

DatagramPacket

datagramPacket是UDP socket发送和接收的数据报;

构造方法:

方法签名方法说明
DatagramPacket(byte[] bytes, int length)

构造一个DatagramPacket用来接收数据报,接收的数据呢保存在字节数组中,接收指定的长度

DatagramPacket(byte[] bytes, int offset, int length, SocketAddress address)构造一个DatagramPacket用来发送数据报,发送的数据为字节数组,从0开始,到指定长度,address指定制定目的主机的IP和端口号

方法:

方法签名方法说明
InetAddress  getAddress()

从接收的数据报中,获取发送端主机IP;或者从发送的数据报中,获取接收端主机IP;

int getPort()从接收的数据报中,获取接收端主机的端口号;或者从发送的数据报中,或缺发送端主机的端口号;
byte[] getData()获取数据报中的数据; 
getSocketAddress()直接获取到当前数据报的IP和端口号;

 

讲完方法了,我们来模拟一个回显服务器,这里就是模拟,回显服务器就是自问自答;

我们来用UDP模拟一下:

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.Socket;
import java.net.SocketException;public class UdpEchoServer {private DatagramSocket socket = null;public UdpEchoServer(int port) throws SocketException {socket = new DatagramSocket(port);//指定端口号,让服务器来使用}public void start() throws IOException {//启动服务器while(true){//循环一次,就意味着处理了一次请求//1读取请求并解析DatagramPacket packet = new DatagramPacket(new byte[4090],4090);socket.receive(packet);String request = new String(packet.getData(),0,packet.getLength());//2根据请求计算响应String response = process(request);//3把响应返回给客户端DatagramPacket packet1 = new DatagramPacket(response.getBytes(),response.getBytes().length,packet.getSocketAddress());socket.send(packet1);//4打印日志System.out.printf("[%s:%d] req: %s, resp: %s\n",packet.getAddress().toString(), packet.getPort(), request, response);}}public String process(String request){return request;}public static void main(String[] args) throws IOException {UdpEchoServer udpEchoServer = new UdpEchoServer(9090);udpEchoServer.start();}
}

模拟服务器:难点用注释标注了,看不明白就来私信我! 

接下来实现客户端代码:

import java.io.IOException;
import java.net.*;
import java.util.Scanner;public class UdpEchoClient {private DatagramSocket socket = null;private String SeverIp;private int SeverPort;public UdpEchoClient(String IP,int port) throws SocketException {this.SeverIp = IP;this.SeverPort = port;socket = new DatagramSocket();}public void start() throws IOException {Scanner scanner = new Scanner(System.in);while(true){System.out.println("请输入要发送的内容");while(!scanner.hasNext()){break;}String request = scanner.nextLine();DatagramPacket datagramPacket = new DatagramPacket(request.getBytes(),request.getBytes().length, InetAddress.getByName(SeverIp),SeverPort);socket.send(datagramPacket);DatagramPacket datagramPacket1 = new DatagramPacket(new byte[4090],4090);socket.receive(datagramPacket1);String response = new String(datagramPacket1.getData(),0,datagramPacket1.getLength());System.out.println(response);}}public static void main(String[] args) throws IOException {UdpEchoClient udpEchoClient = new UdpEchoClient("127.0.0.1",9090);udpEchoClient.start();}}

我们把两个代码的都运行下 

客户端

服务器


4,TCP流套接字编程

接下来我们来实现TCP的网络编程,还是先来学习一下方法:

SeverSocket

SeverSocket呢是创建TCP服务端Socket的ApI;

构造方法:

方法签名方法说明
SeverSocket(int port)创建一个服务端流套接字Socket,并绑定到指定端口

方法:

方法签名方法说明
Socket accept()开始监听指定端口(创建时绑定的端口),有客户端连接后,返回一个服务端Socket对象,并基于该Socket建立与客户端的连接,否则阻塞等待;
void close()关闭此套接字;

Socket

socket是客户端Socket,或服务端中接收到客户端建立连接(accept)的请求后,返回的服务端Socket;

构造方法:

方法签名方法说明
Socket(String host,int port)创建一个客户端流套接字Socket,并与对应IP的主机上,对应端口的进程建立连接;

方法:

方法签名方法说明
inerAddress  getInetAddress()返回套接字所连接的地址
inputStream  getInputStream()返回此套接字的输入流
OutputStream  getOutputStream()返回此套接字的输出流

服务端

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class TcpEchoServer {private ServerSocket serverSocket = null;public TcpEchoServer(int port) throws IOException {serverSocket = new ServerSocket(port);}public void start() throws IOException {System.out.println("启动服务器");ExecutorService executorService = Executors.newCachedThreadPool();while(true){Socket socketClient = serverSocket.accept();executorService.submit(()->{try {processConnection(socketClient);} catch (IOException e) {throw new RuntimeException(e);}});}}public void processConnection(Socket socketClient) throws IOException {System.out.println("客户端上线"+ socketClient.getInetAddress()+socketClient.getPort());try(InputStream inputStream = socketClient.getInputStream();OutputStream outputStream = socketClient.getOutputStream()){Scanner scanner = new Scanner(inputStream);PrintWriter printWriter = new PrintWriter(outputStream);while (true){if(!scanner.hasNext()){System.out.println("客户端下线"+ socketClient.getInetAddress()+socketClient.getPort());break;}String request = scanner.nextLine();String response = process(request);printWriter.println(response);printWriter.flush();System.out.printf("[%s:%d] req: %s, resp: %s\n", socketClient.getInetAddress(), socketClient.getPort(),request, response);}}}public String process(String request){return request;}public static void main(String[] args) throws IOException {TcpEchoServer tcpEchoServer = new TcpEchoServer(9090);tcpEchoServer.start();}
}


这里引入线程池来处理多个请求,避免其他请求发来处理不了的情况;

客户端:
 

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;public class TcpEchoClient {private Socket socket = null;public TcpEchoClient(String IP,int port) throws IOException {socket = new Socket(IP,port);}public void start() throws IOException {Scanner scanner = new Scanner(System.in);try(InputStream inputStream = socket.getInputStream();OutputStream outputStream = socket.getOutputStream()){Scanner scanner1 = new Scanner(inputStream);PrintWriter printWriter = new PrintWriter(outputStream);while(true){System.out.println("请输入要发送的信息");String request = scanner.nextLine();printWriter.println(request);printWriter.flush();String response = scanner1.nextLine();System.out.println(response);}}}public static void main(String[] args) throws IOException {TcpEchoClient tcpEchoClient = new TcpEchoClient("127.0.0.1",9090);tcpEchoClient.start();}
}

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

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

相关文章

MySQL性能调优(三):MySQL中的系统库(mysql系统库)

文章目录 MySQL性能调优数据库设计优化查询优化配置参数调整硬件优化 MySQL中的系统库1.5.Mysql中mysql系统库1.5.1.权限系统表1.5.2.统计信息表1.5.2.1.innodb_table_stats1.5.2.2.innodb_index_stats 1.5.3.日志记录表1.5.3.1. general_log1.5.3.2. slow_log 1.5.4.InnoDB中的…

多个路由器互通(静态路由)无单臂路由(简单版)

多个路由器互通(静态路由)无单臂路由(简单版) 开启端口并配ip地址 维护1 Router>en Router#conf t Router(config)#int g0/0 Router(config-if)#no shutdown Router(config-if)#ip address 192.168.10.254 255.255.255.0 Ro…

关于 AI驱动的智慧家居、智慧城市、智慧交通、智慧医疗和智慧生活 的详细解析,涵盖其定义、核心技术、应用场景、典型案例及未来趋势

以下是关于 AI驱动的智慧家居、智慧城市、智慧交通、智慧医疗和智慧生活 的详细解析,涵盖其定义、核心技术、应用场景、典型案例及未来趋势: 一、AI智慧家居 1. 定义与核心功能 定义:通过AI与物联网(IoT)技术&#…

【ESP32|音频】一文读懂WAV音频文件格式【详解】

简介 最近在学习I2S音频相关内容,无可避免会涉及到关于音频格式的内容,所以刚开始接触的时候有点一头雾水,后面了解了下WAV相关内容,大致能够看懂wav音频格式是怎么样的了。本文主要为后面ESP32 I2S音频系列文章做铺垫&#xff0…

端侧大模型综述On-Device Language Models: A Comprehensive Review

此为机器翻译,仅做个人学习使用 设备端语言模型:全面回顾 DOI:10.48550/arXiv.2409.00088 1 摘要 大型语言模型 (LLM) 的出现彻底改变了自然语言处理应用程序,由于减少延迟、数据本地化和个性化用户体验…

推流265视频,网页如何支持显示265的webrtc

科技发展真快,以前在网页上(一般指谷歌浏览器),要显示265的视频流,都是很鸡肋的办法,要么转码,要么用很慢的hls,体验非常不好,而今谷歌官方最新的浏览器已经支持265的web…

redis的sorted set的应用场景

Redis 的 Sorted Set(有序集合,简称 ZSet) 结合了 Set 的去重特性 和 按分数(score)排序 的特性,非常适合需要 高效排序 或 范围查询 的场景。以下是它的典型应用场景及示例: 实时排行榜 场景&…

18-21源码剖析——Mybatis整体架构设计、核心组件调用关系、源码环境搭建

学习视频资料来源:https://www.bilibili.com/video/BV1R14y1W7yS 文章目录 1. 架构设计2. 核心组件及调用关系3. 源码环境搭建3.1 测试类3.2 实体类3.3 核心配置文件3.4 映射配置文件3.5 遇到的问题 1. 架构设计 Mybatis整体架构分为4层: 接口层&#…

未启用CUDA支持的PyTorch环境** 中使用GPU加速解决方案

1. 错误原因分析 根本问题:当前安装的PyTorch是CPU版本,无法调用GPU硬件加速。当运行以下代码时会报错:model YOLO("yolov8n.pt").to("cuda") # 或 .cuda()2. 解决方案步骤 步骤1:验证CUDA可用性 在Pyth…

JVM-基于Hotspot

前言 Java虚拟机(Java Virtual Machine简称JVM)是运行所有Java程序的抽象计算机,是Java语言的运行环境,其主要任务为将字节码装载到内部,解释/编译为对应平台上的机器指令执行。 Java虚拟机规范定义了一个抽象的——…

智能合约安全审计平台——可视化智能合约漏洞扫描

目录 可视化智能合约漏洞扫描 —— 理论、实践与安全保障1. 引言2. 理论背景与漏洞原理2.1 智能合约简介2.2 常见漏洞类型2.3 漏洞扫描与安全评估原理3. 系统架构与工作流程3.1 系统总体架构3.2 模块说明4. 漏洞扫描流程详解4.1 代码上传与静态解析4.2 漏洞模式检测4.3 风险评估…

【MySQL数据库】数据类型详解

目录 数据类型tinyint类型(整形)bit类型小数浮点数 float、doubledecimal 字符串类型charvarcharchar与varchar的比较 日期时间类型enum和set总结 数据类型 tinyint类型(整形) 例: mysql> create table tt1(num tinyint);mysql> insert into tt1 values(1)…

咪咕MG101_晨星MSO9380芯片_安卓5.1.1_免拆卡刷固件包

咪咕MG101_晨星MSO9380芯片_安卓5.1.1_免拆卡刷固件包(内有教程) 刷机教程简单说明: 1、把下载好的刷机包,U盘里建立一个upgrade文件夹,固件放入此文件夹里,放入U盘中,注意升级包为压缩包不要对…

CS61A:STRING REPRESENTATION

Python 规定所有对象都应该产生两种不同的字符串表示形式:一种是人类可解释的文本,另一种是 Python 可解释的表达式。字符串的构造函数 str 返回一个人类可读的字符串。在可能的情况下,repr 函数会返回一个计算结果相等的 Python 表达式。rep…

LangChain缓存嵌入技术完全指南:CacheBackedEmbedding原理与实践(附代码示例)

一、嵌入缓存技术背景与应用场景 1.1 为什么需要嵌入缓存? 算力消耗问题:现代嵌入模型(如text-embedding-3-small)单次推理需要约0.5-1秒/文本 资源浪费现状:实际业务中约30%-60%的文本存在重复计算 成本压力&#…

精益数据分析(3/126):用数据驱动企业发展的深度解析

精益数据分析(3/126):用数据驱动企业发展的深度解析 大家好!一直以来,我都坚信在当今竞争激烈的商业环境中,数据是企业获得竞争优势的关键。最近深入研究《精益数据分析》这本书,收获颇丰&…

wpf ScaleTransform

在WPF中,ScaleTransform是用于实现元素缩放的核心类,属于System.Windows.Media命名空间下的变换类型。以下是其主要特性与使用方式的总结: ‌核心属性‌ ‌缩放比例‌ ScaleX:水平方向缩放比例(默认1.0,即…

用纯Qt实现GB28181协议/实时视频/云台控制/预置位/录像回放和下载/事件订阅/语音对讲

一、前言 在技术的长河中探索,有些目标一旦确立,便如同璀璨星辰,指引着我们不断前行。早在2014年,我心中就种下了用纯Qt实现GB28181协议的种子,如今回首,一晃十年已逝,好在整体框架和逻辑终于打…

0x01、Redis 主从复制的实现原理是什么?

Redis 主从复制概述 Redis 的主从复制是一种机制,允许一个主节点(主实例)将数据复制到一个或多个从节点(从实例)。通过这一机制,从节点可以获取主节点的数据并与之保持同步。 复制流程 开始同步&#xf…

整活 kotlin + springboot3 + sqlite 配置一个 SQLiteCache

要实现一个 SQLiteCache 也是很简单的只需要创建一个 cacheManager Bean 即可 // 如果配置文件中 spring.cache.sqlite.enable false 则不启用 Bean("cacheManager") ConditionalOnProperty(name ["spring.cache.sqlite.enable"], havingValue "t…