Java 基础知识九(网络编程)

embedded/2024/9/23 20:27:05/
UDP

DatagramSocket:通讯的数据管道

-send 和receive方法

-(可选,多网卡)绑定一个IP和Port
DatagramPacket
-集装箱:封装数据
-地址标签:目的地IP+Port

package org.example.net;import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;public class UdpRecv {public static void main(String[] args) throws Exception {DatagramSocket ds = new DatagramSocket(3000);byte[] buf = new byte[1024];DatagramPacket dp = new DatagramPacket(buf, 1024);System.out.println("UdpRecv:我在等待信息");ds.receive(dp);System.out.println("UdpRecv:我接收到信息");String strRecv = new String(dp.getData(), 0, dp.getLength()) + " from " + dp.getAddress().getHostAddress() + ":" + dp.getPort();System.out.println(strRecv);Thread.sleep(1000);System.out.println("UdpRecv:我要发送信息");String str = "hello world 222";DatagramPacket dp2 = new DatagramPacket(str.getBytes(), str.length(), InetAddress.getByName("127.0.0.1"), dp.getPort());ds.send(dp2);System.out.println("UdpRecv:我发送信息结束");ds.close();}
}
package org.example.net;import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;public class UdpSend {public static void main(String[] args) throws Exception {DatagramSocket ds = new DatagramSocket();String str = "hello world";DatagramPacket dp = new DatagramPacket(str.getBytes(), str.length(), InetAddress.getByName("127.0.0.1"), 3000);System.out.println("UdpSend:我要发送信息");ds.send(dp);System.out.println("UdpSend:我发送信息结束");Thread.sleep(1000);byte[] buf = new byte[1024];DatagramPacket dp2 = new DatagramPacket(buf, 1024);System.out.println("UdpSend:我在等待信息");ds.receive(dp2);System.out.println("UdpSend:我接收到信息");String str2 = new String(dp2.getData(), 0, dp2.getLength()) + " from " + dp2.getAddress().getHostAddress() + ":" + dp2.getPort();System.out.println(str2);ds.close();}
}
TCP

TCP协议:有链接、保证可靠的无误差通讯

-1)服务器:创建一个ServerSocket,等待连接
-2)客户机:创建一个Socket,连接到服务器-

3)服务器:ServerSocket接收到连接,创建一个Socket和客户的Socket建立专线连接,后续服务器和客户机的对话(这一对Sock会在一个单独的线程(服务器端)上运行

4)服务器的ServerSocket继续等待连接,返回1

ServerSocket: 服务器码头
需要绑定port
如果有多块网卡,需要绑定一个IP地址
Socket: 运输通道
-客户端需要绑定服务器的地址和Port
-客户端往Socket输入流写入数据,送到服务端-客户端从Socket输出流取服务器端过来的数据
-服务端反之亦然

服务端等待响应时,处于阻塞状态
服务端可以同时响应多个客户端
服务端每接受一个客户端,就启动一个独立的线程与之对应
客户端或者服务端都可以选择关闭这对Socket的通道
实例
-服务端先启动,且一直保留
-客户端后启动,可以先退出

package org.example.net;import java.io.*;
import java.net.InetAddress;
import java.net.Socket;public class TcpClient {public static void main(String[] args) {try {Socket s = new Socket(InetAddress.getByName("127.0.0.1"),8001);//需要服务端先开启//同一个通道,服务端的输出流就是客户端的输入流;服务端的输入流就是客户端的输出流// 开启通道的输入流InputStream ips =s.getInputStream();BufferedReader brNet = new BufferedReader(new InputStreamReader(ips));OutputStream ops = s.getOutputStream();//开启通道的输出流DataOutputStream dos = new DataOutputStream(ops);BufferedReader brKey = new BufferedReader(new InputStreamReader(System.in));while (true) {String strWord = brKey.readLine();if (strWord.equalsIgnoreCase("quit")) {break;}else{System.out.println("I want to send:" + strWord);dos.writeBytes(strWord + System.getProperty("line.separator") );System.out.println("Server said :" + brNet.readLine());}}}catch (IOException e){e.printStackTrace();}}
}
package org.example.net;import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;public class TcpServer {public static void main(String[] args) {try {ServerSocket ss = new ServerSocket(8001);//驻守在8001端口Socket s = ss.accept();//阻寒,等到有客户端连接上来System.out.println("welcome to the java world");InputStream ips = s.getInputStream();//有人连上来,打开输入流OutputStream ops = s.getOutputStream();//打开输出流// 同一个通道,服务端的输出流就是客户端的输入流;服务端的输入流就是客户端的输出流ops.write("Hello,client!".getBytes()); //输出一句话给客户端BufferedReader br = new BufferedReader(new InputStreamReader(ips));//从客户端读取一句话System.out.println("client said:" + br.readLine());ips.close();ops.close();s.close();ss.close();}catch (IOException e){e.printStackTrace();}}
}

server2 处理多客户端

package org.example.net;import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;public class TcpServer2 {public static void main(String[] args) {try {ServerSocket ss = new ServerSocket(8001);//驻守在8001端口while (true){Socket s = ss.accept();//阻寒,等到有客户端连接上来System.out.println("a new client coming");new Thread(new Worker(s)).start();}}catch (IOException e){e.printStackTrace();}}
}
package org.example.net;import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;public class Worker implements Runnable {Socket s;public Worker(Socket s) {this.s = s;}@Overridepublic void run() {try {System.out.println("server has started");InputStream ips = s.getInputStream();//有人连上来,打开输入流OutputStream ops = s.getOutputStream();//打开输出流BufferedReader br = new BufferedReader(new InputStreamReader(ips));DataOutputStream dos = new DataOutputStream(ops);while (true) {String strWord = br.readLine();System.out.println("client said:" + strWord + ":" + strWord.length());if (strWord.equalsIgnoreCase("quit")) {break;}String strEcho = strWord + " echo";// dos.writeBytes(strWord + System.getProperty("line.separator"));System.out.println("Server said :" + strWord + "---->" + strEcho);dos.writeBytes(strWord + "---->" + strEcho + System.getProperty("line.separator"));}br.close();//关闭包装类,会自动关闭包装类中所包装过的底层类。所以不用调用ips.close()dos.close();s.close();} catch (Exception e) {e.printStackTrace();}}
}
HTTP

Java HTTP编程(java.net包)

-支持模拟成浏览器的方式去访问网页

-URL,Uniform Resource Locator,代表一个资源http://www.ecnu.edu.cn/index.html?a=1&b=2&c=3

-URLConnection
获取资源的连接器
根据URL的openConnection(方法获得URLConnection

connect方法,建立和资源的联系通道

getInputStream方法,获取资源的内容

package org.example.net;import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.List;
import java.util.Map;public class URLConnectionGetTest {public static void main(String[] args) {try {String urlName = "https://www.baidu.com";URL url = new URL(urlName);URLConnection connection = url.openConnection();connection.connect();//打印http的头部信息Map<String, List<String>> headers = connection.getHeaderFields();for (Map.Entry<String, List<String>> entry : headers.entrySet()) {String key = entry.getKey();for (String value : entry.getValue()) {System.out.println(key + ":" + value);}}//输出将要收到的内容属性信息System.out.println("-----------------------");System.out.println("getcontentType:"+connection.getContentType());System.out.println("getcontentLength:"+ connection.getContentLength());System.out.println("getcontentEncoding:?"+ connection.getContentEncoding());System.out.println("getDate:"+ connection.getDate());System.out.println("getExpiration:"+ connection.getExpiration());System.out.println("getLastModifed:"+ connection.getLastModified());System.out.println("----------");BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream(),"UTF-8"));//输出收到的内容String line ="";while ((line= br.readLine())!= null){System.out.println(line);}} catch (Exception e) {e.printStackTrace();}}
}
package org.example.net;import java.io.*;
import java.net.*;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;public class URLConnectionPostTest {public static void main(String[] args) throws IOException {String urlstring = "https://tools.usps.com/go/zipLookupAction.action";Object userAgent = "HTTPie/0.9.2";Object redirects = "1";CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ALL));Map<String, String> params = new HashMap<String, String>();params.put("tAddress", "1 Market street");params.put("tcity", "San Francisco");params.put("sstate", "CA");String result = doPost(new URL(urlstring), params,userAgent == null ? null : userAgent.toString(),redirects == null ? -1 : Integer.parseInt(redirects.toString()));System.out.println(result);}public static String doPost(URL url, Map<String, String> nameValuePairs, String userAgent, int redirects) throws IOException {HttpURLConnection connection = (HttpURLConnection) url.openConnection();if (userAgent != null)connection.setRequestProperty("User-Agent", userAgent);if (redirects >= 0)connection.setInstanceFollowRedirects(false);connection.setDoOutput(true);//输出请求的参数try (PrintWriter out = new PrintWriter(connection.getOutputStream())) {boolean first = true;for (Map.Entry<String, String> pair : nameValuePairs.entrySet()) {//参数必须这样拼接a = 1 & b = 2 & c = 3if (first) {first = false;} else {out.print('&');}String name = pair.getKey();String value = pair.getValue();out.print(name);out.print('=');out.print(URLEncoder.encode(value, "UTF-8"));}}String encoding = connection.getContentEncoding();if (encoding == null){encoding = "UTF-8";}if (redirects > 0) {int responseCode = connection.getResponseCode();System.out.println("responsecode:" + responseCode);if (responseCode == HttpURLConnection.HTTP_MOVED_PERM|| responseCode == HttpURLConnection.HTTP_MOVED_TEMP|| responseCode == HttpURLConnection.HTTP_SEE_OTHER) {String location = connection.getHeaderField("Location");if (location != null) {URL base = connection.getURL();connection.disconnect();return doPost(new URL(base, location), nameValuePairs, userAgent, redirects - 1);}}} else if (redirects == 0) {throw new IOException("Too many redirects");}StringBuilder response = new StringBuilder();try (Scanner in = new Scanner(connection.getInputStream(),encoding)){while(in.hasNextLine()){response.append(in.nextLine());response.append("\n");}} catch (IOException e) {InputStream err = connection.getErrorStream();if (err == null) throw e;try (Scanner in = new Scanner(err)) {response.append(in.nextLine());response.append("\n");}}return response.toString();}
}

HTTPClient

java.net.http包

取代URLConnection 支持HTTP/1.1和HTTP/2 实现大部分HTTP方法主要类
-HttpClient -HttpRequest- HttpResponse

package org.example.net;import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;public class JDKHttpClientGetTest {public static void main(String[] args) throws IOException, InterruptedException {doGet();}public static void doGet() {try {HttpClient client = HttpClient.newHttpClient();HttpRequest request = HttpRequest.newBuilder(URI.create("http://www.baidu.com")).build();HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());System.out.println(response.body());} catch (Exception e) {e.printStackTrace();}}
}

Httpcomponents
hc.apache.org,Apache出品从HttpClient进化而来,是一个集成的Java HTIP工具包
-实现所有HTTP方法:get/post/put/delete
-支持自动转向
-支持https协议
-支持代理服务器等

NIO

·Buffer 缓冲区,一个可以读写的内存区域-ByteBuffer, CharBuffer, DoubleBuffer, IntBuffer, LongBufferShortBuffer (StringBuffer 不是Buffer缓冲区)
四个主要属性
capacity 容量,position 读写位置
limit 界限,mark标记,用于重复一个读/写操作

Channel 通道
全双工的,支持读/写(而Stream流是单向的)
-支持异步读写
-和Buffer配合,提高效率
-ServerSocketChannel 服务器TCP Socket 接入通道,接收客户端-SocketChannel TCP Socket通道,可支持阻寒/非阻塞通讯-DatagramChannel UDp 通道
-FileChannel 文件通道

elector多路选择器
-每隔一段时间,不断轮询注册在其上的Channel-如果有一个Channel有接入、读、写操作,就会被轮询出来进行后续IO操作

-根据SelectionKey可以获取相应的Channel,

-避免过多的线程

-SelectionKey四种类型
·OP_CONNECT
·OP_ACCEPT
·OP READ
·OP WRITE

package org.example.NIO;import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;
import java.util.UUID;public class NioClient {public static void main(String[] args) {String host = "127.0.0.1";int port = 8001;Selector selector = null;SocketChannel socketchannel = null;try {selector = Selector.open();socketchannel = SocketChannel.open();socketchannel.configureBlocking(false);//非阻塞//如果直接连接成功,则注册到多路复用器上,发送请求消息,读应答if (socketchannel.connect(new InetSocketAddress(host, port))) {socketchannel.register(selector, SelectionKey.OP_READ);doWrite(socketchannel);} else {socketchannel.register(selector, SelectionKey.OP_CONNECT);}} catch (IOException e) {e.printStackTrace();}while (true) {try {selector.select(1000);Set<SelectionKey> selectedKeys = selector.selectedKeys();Iterator<SelectionKey> it = selectedKeys.iterator();SelectionKey key = null;while (it.hasNext()) {key = it.next();it.remove();try {handleInput(selector, key);} catch (Exception e) {if (key != null) {key.cancel();if (key.channel() != null)key.channel().close();}}}} catch (Exception ex) {ex.printStackTrace();}}}public static void doWrite(SocketChannel sc)throws IOException {byte[] str = UUID.randomUUID().toString().getBytes();ByteBuffer writeBuffer = ByteBuffer.allocate(str.length);writeBuffer.put(str);writeBuffer.flip();sc.write(writeBuffer);}public static void handleInput(Selector selector, SelectionKey key) throws IOException, InterruptedException {if(key.isValid()) {//判断是否连接成功SocketChannel sc = (SocketChannel) key.channel();if (key.isConnectable()) {if (sc.finishConnect()) {sc.register(selector, SelectionKey.OP_READ);}}if (key.isReadable()) {ByteBuffer readBuffer = ByteBuffer.allocate(1024);int readBytes = sc.read(readBuffer);if (readBytes > 0) {readBuffer.flip();byte[] bytes = new byte[readBuffer.remaining()];readBuffer.get(bytes);String body = new String(bytes, "UTF-8");System.out.println("server said :" + body);} else if (readBytes < 0) {//对端链路关闭key.cancel();sc.close();} else; // 读到字节,忽略}Thread.sleep(5000);doWrite(sc);}}
}
package org.example.NIO;import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;public class NioServer {public static void main(String[] args) throws IOException {int port = 8001;Selector selector = null;ServerSocketChannel servChannel = null;try {selector = selector.open();servChannel = ServerSocketChannel.open();servChannel.configureBlocking(false);servChannel.socket().bind(new InetSocketAddress(port), 1024);servChannel.register(selector, SelectionKey.OP_ACCEPT);System.out.println("服务器在8001端口守候");} catch (IOException e) {e.printStackTrace();System.exit(1);}while (true) {try {selector.select(1000);Set<SelectionKey> selectedKeys = selector.selectedKeys();Iterator<SelectionKey> it = selectedKeys.iterator();SelectionKey key = null;while (it.hasNext()) {key = it.next();it.remove();try {handleInput(selector, key);} catch (Exception e) {if (key != null) {key.cancel();if (key.channel() != null)key.channel().close();}}}} catch (Exception ex) {ex.printStackTrace();}try {Thread.sleep(500);} catch (Exception ex) {ex.printStackTrace();}}}public static void handleInput(Selector selector, SelectionKey key) throws IOException {if (key.isValid()) {//判断是否连接成功if (key.isAcceptable()) {ServerSocketChannel ssc = (ServerSocketChannel) key.channel();SocketChannel sc = ssc.accept();sc.configureBlocking(false);sc.register(selector, SelectionKey.OP_READ);}if (key.isReadable()) {SocketChannel sc = (SocketChannel) key.channel();ByteBuffer readBuffer = ByteBuffer.allocate(1024);int readBytes = sc.read(readBuffer);if (readBytes > 0) {readBuffer.flip();byte[] bytes = new byte[readBuffer.remaining()];readBuffer.get(bytes);String request = new String(bytes, "UTF-8");System.out.println("server said :" + request);String response = request + " 666";doWrite(sc,response);} else if (readBytes < 0) {//对端链路关闭key.cancel();sc.close();} else; // 读到字节,忽略}}}public static void doWrite(SocketChannel channel,String response) throws IOException {if (response != null && response.trim().length() > 0) {byte[] bytes = response.getBytes();ByteBuffer writeBuffer = ByteBuffer.allocate(bytes.length);writeBuffer.put(bytes);writeBuffer.flip();channel.write(writeBuffer);}}
}
AIO

package org.example.Aio;import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.util.UUID;public class AioClient {public static void main(String[] a){try {AsynchronousSocketChannel channel =  AsynchronousSocketChannel.open();channel.connect(new InetSocketAddress("localhost", 8001), null, new CompletionHandler<Void, Void>() {public void completed(Void result, Void attachment){String str = UUID.randomUUID().toString();channel.write(ByteBuffer.wrap(str.getBytes()), null, new CompletionHandler<Integer, Object>() {@Overridepublic void completed(Integer result, Object attachment){try {System.out.println("write " +str + " , and wait response");ByteBuffer buffer = ByteBuffer.allocate(1024);channel.read(buffer, buffer, new CompletionHandler<Integer, ByteBuffer>() {@Overridepublic void completed(Integer result_num, ByteBuffer attachment) {attachment.flip();CharBuffer charBuffer = CharBuffer.allocate(1024);CharsetDecoder decoder = Charset.defaultCharset().newDecoder();decoder.decode(attachment, charBuffer, false);charBuffer.flip();String data = new String(charBuffer.array(), 0, charBuffer.limit());System.out.println("server said: " + data);try {channel.close();}catch (Exception e){e.printStackTrace();}}@Overridepublic void failed(Throwable exc, ByteBuffer attachment) {System.out.println("read error "+ exc.getMessage());}});channel.close();}catch (Exception e){e.printStackTrace();}}public void failed(Throwable exc, Object attachment){System.out.println("write error ");}});}public void failed(Throwable exc, Void attachment){System.out.println("faild ");}});Thread.sleep(10000);}catch (Exception e){e.printStackTrace();}}
}
package org.example.Aio;import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.AsynchronousByteChannel;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;public class AioServer {public static void main(String[] args) throws IOException {AsynchronousServerSocketChannel server = AsynchronousServerSocketChannel.open();server.bind(new InetSocketAddress("localhost", 8001));System.out.println(" server is witing at port 8001");server.accept(null, new CompletionHandler<AsynchronousSocketChannel, Object>() {@Overridepublic void completed(AsynchronousSocketChannel channel, Object attchment){server.accept(null, this);ByteBuffer buffer = ByteBuffer.allocate(1024);channel.read(buffer, buffer, new CompletionHandler<Integer, ByteBuffer>() {@Overridepublic void completed(Integer result_num, ByteBuffer attachment) {attachment.flip();CharBuffer charBuffer = CharBuffer.allocate(1024);CharsetDecoder decoder = Charset.defaultCharset().newDecoder();decoder.decode(attachment, charBuffer, false);charBuffer.flip();String data = new String(charBuffer.array(),0,charBuffer.limit());System.out.println("client said: "+data);channel.write(ByteBuffer.wrap((data + " 666").getBytes()));try {channel.close();}catch (Exception e){e.printStackTrace();}};@Overridepublic void failed(Throwable exc, ByteBuffer attachment) {System.out.println("read error "+ exc.getMessage());}});}public void failed(Throwable exc, Object attachment){System.out.println("failed "+ exc.getMessage());}});while (true){try {Thread.sleep(5000);}catch (InterruptedException e){e.printStackTrace();}}}}


http://www.ppmy.cn/embedded/114374.html

相关文章

Matlab R2024B软件安装教程

一、新版本特点 MATLAB R2024B版本带来了众多新特性和改进&#xff0c;旨在提升用户的内容创作体验和工程效率。以下是该版本的一些主要特点&#xff1a; 1. 性能提升和优化&#xff1a;R2024B版本在性能上进行了显著优化&#xff0c;无论是在提问、回答问题、发布新技巧还是…

mybatisplus中id生成策略

使用Tableld(value,type) 1.typeIdType.AUTO自增主键 2.typeIdType.ASSIGN,雪花算法生成 mybatisplus id生成策略全局配置 配置表前缀以及id生成策略 mybatis-plus:global-config:db-config:id-type: autotable-prefix: :t_

.Net Core 生成管理员权限的应用程序

创建一个ASP.NET Core Web API项目 给解决方案设置一个名称 选择一个目标框架&#xff0c;这里选择的是 .NET 8.0框架 在Porperties文件夹中添加一个app.manifest文件 设置app.manifest文件属性&#xff0c;生成操作设置为嵌入的资源 双击解决方案名称&#xff0c;编辑WebAppli…

微服务_入门1

文章目录 一、 认识微服务二、 微服务演变2.1、 单体架构2.2、 分布式架构2.3、 微服务2.4、 微服务方案对比 三、 注册中心3.1、 Eureka3.2、 Nacos3.2.1、服务分级存储模型3.2.2、权重配置3.2.3、环境隔离 一、 认识微服务 二、 微服务演变 随着互联网行业的发展&#xff0c;…

25届计算机专业选题推荐-基于微信小程序的校园快递驿站代收管理系统

&#x1f496;&#x1f525;作者主页&#xff1a;毕设木哥 精彩专栏推荐订阅&#xff1a;在 下方专栏&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; 实战项目 文章目录 实战项目 一、基于微信小程序的校园快递驿…

spring security OAuth2 搭建资源服务器以及授权服务器/jdbc/jwt两种方案

一、认证服务器基于jdbc方式 如果不懂请移步上一篇文章&#xff1a;Spring security OAuth2 授权服务器搭建-CSDN博客 在上一篇文章中&#xff0c;TokenStore的默认实现为 InHenoryTokenStore 即内存存储&#xff0c;对于 CLient 信息&#xff0c;userDetaitsServce 接负责从存…

C++自动寻径算法

测试 #include <iostream> #include "source/AStar.hpp"int main() {AStar::Generator generator;generator.setWorldSize({25, 25});generator.setHeuristic(AStar::Heuristic::euclidean);generator.setDiagonalMovement(true);generator.addCollision({1, …

平滑损失对生成图像的影响和使用场景

文章目录 1. 减少视觉伪影2. 模拟自然场景的特性3. 增强图像的整体协调性4. 克服技术限制5. 适应人类视觉感知 使用场景卡通风格可能不适用1. 卡通风格的特点 2. 考虑引入平滑损失的场景3. 考虑不引入平滑损失的场景4. 实验和调整 平滑损失&#xff08;Smooth Loss&#xff09;…