当前位置: 首页 > news >正文

【网络~】

网络

  • 一级目录
    • 二、socket套接字
      • 三、UDP数据报套接字
        • 四、TCP流套接字

一级目录

1.局域网、广域网

2.IP地址是什么?

IP地址是标识主机在网络上的地址
IP地址是如何组成的?
点分十进制,将32位分为四个部分,每个部分一个字节,范围是0-255

3.端口号是什么?

端口号是区分一台主机上不同的应用程序。

4.客户端和服务器

客户端是发起请求方。服务器是响应请求。
1.一对一形式:客户端发送一个请求,服务器响应一个请求;
2.一对多形式:客户端发送一个请求,服务器响应多个请求;
3.多对一形式:客户端发送多个请求,服务器响应一个请求;
4.多对多形式:客户端发送多个请求,服务器响应多个请求。

5.协议

主机和主机之间通信需要遵循一些协议。
两台主机之间通信,需要通过一个 五元组 来描述通信
五元组是什么?
源ip,源端口,目的ip,目的端口,协议类型。

6.协议分段

1.OSI模型:物理层->数据链路层->网络层->运输层->会话层->表示层->应用层
2.TCP/IP五层模型:物理层->数据链路层->网络层->运输层->应用层
应用层:应用程序
运输层:只关注起点和终点
网络层:关注网络中任意两台机器的网络通信路径和具体的传输方式
数据链路层:相邻主机之间的数据传输
物理层:网络传输的基础设施
下层协议给上层协议提供功能支持,上层协议依赖下层协议。

7.网络编程

网络编程是什么?
在网络上,不同进程通过编码方式进行数据通信,叫做网络编程。

二、socket套接字

1.socket套接字是什么?

socket套接字是操作系统提供的网络通信技术,是基于TCP/IP协议的操作基本单元。基于socket应用程序开发就是网络编程。

2.socket套接字的分类

1.数据报套接字:基于UDP协议
2.流套接字:基于TCP协议
UDP和TCP的区别:
UDP:1.无连接;2.不可靠传输;3.面向数据报;4.全双工。
TCP:1.有连接;2.可靠传输;3.面向字节流;4.全双工。
什么是可靠传输?
发送方知道接受方是否正确收到信息。
不可靠传输:发送发不知道接受方是否正确收到信息。

三、UDP数据报套接字

1.Java数据报套接字通信模型(基于UDP协议)

DatagramSocket:描述一个soket对象,在操作系统中,一切皆文件,管理硬件设备和软件资源,都是通过文件的方式来管理,网卡是硬件设备,要想操作网卡,需要写一个socket文件,通过读写socket文件来操作网卡。
socket实际上是一个文件描述符表。
DatagramPacket:描述一个UDP数据报。

2.利用DatagramSocket和DatagramPacket来写一个回显服务器(UDP socket)

//客户端
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.util.Scanner;public class UdpEchoClient02 {DatagramSocket socket=null;String serverIp;int serverPort;public UdpEchoClient02(String serverIp,int serverPort) throws SocketException {this.serverIp=serverIp;this.serverPort=serverPort;socket=new DatagramSocket();}//客户端需要知道服务器的ip地址和端口号public void start() throws IOException {Scanner in=new Scanner(System.in);while (true){System.out.println("client02:用户输入请求->");String request=in.next();if(request.equals("exist")){System.out.println("系统退出");return;}DatagramPacket requestPacket=new DatagramPacket(request.getBytes(),request.getBytes().length,InetAddress.getByName(serverIp),serverPort);socket.send(requestPacket);DatagramPacket responsePacket=new DatagramPacket(new byte[4096],4096);socket.receive(responsePacket);String response=new String(responsePacket.getData(),0,responsePacket.getLength());String log=String.format("[%s,%s],request:%s,response:%s",responsePacket.getAddress(),responsePacket.getPort(),request,response);System.out.println(log);}}public static void main(String[] args) throws IOException {UdpEchoClient02 udpEchoClient02=new UdpEchoClient02("127.0.0.1",7010);udpEchoClient02.start();}
}
//服务器端:
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;//服务器端
public class UdpEchoService02 {DatagramSocket socket=null;public UdpEchoService02(int port) throws SocketException {socket=new DatagramSocket(port);}public void start() throws IOException {System.out.println("service02:启动服务器");while(true){DatagramPacket requestPacket=new DatagramPacket(new byte[4096],4096);socket.receive(requestPacket);String request=new String(requestPacket.getData(),0,requestPacket.getLength());String response=getResponse(request);DatagramPacket responsePacket=new DatagramPacket(response.getBytes(),response.getBytes().length,requestPacket.getSocketAddress());socket.send(responsePacket);String log=String.format("[%s,%d]:request:%s;response:%s",requestPacket.getAddress(),requestPacket.getPort(),request,response);System.out.println(log);}}public String getResponse(String request){return request;}public static void main(String[] args) throws IOException {UdpEchoService02 udpEchoService02=new UdpEchoService02(7010);udpEchoService02.start();}
}

结果:
在这里插入图片描述
在这里插入图片描述

3."翻译"程序

英译汉:客户端输入请求为英文单词,返回的响应式中文解释。

//客户端
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.util.Scanner;//客户端
public class UdpClient {DatagramSocket socket=null;String serverIp;int serverPort;public UdpClient(String serverIp,int serverPort) throws SocketException {this.serverIp=serverIp;this.serverPort=serverPort;socket=new DatagramSocket();}public void start() throws IOException {Scanner in=new Scanner(System.in);while(true){//1.用户输入请求String request=in.next();if(request.equals("exit")){System.out.println("系统退出");return;}//2.根据用户输入构造请求,并将请求发送给服务器DatagramPacket requestPacket=new DatagramPacket(request.getBytes(),request.getBytes().length,InetAddress.getByName(serverIp),serverPort);socket.send(requestPacket);//3.接收服务器的响应DatagramPacket responsePacket=new DatagramPacket(new byte[4096],4096);socket.receive(responsePacket);//4.解析服务器响应String response=new String(responsePacket.getData(),0,responsePacket.getLength());//5.日志打印String log=String.format("[%s,%d],request:%s,response:%s",responsePacket.getAddress(),responsePacket.getPort(),request,response);System.out.println(log);}}public static void main(String[] args) throws IOException {UdpClient udpClient=new UdpClient("127.0.0.1",9090);udpClient.start();}
}
//服务器
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.util.HashMap;//服务器端
public class UdpServer {DatagramSocket socket=null;HashMap<String,String> hashMap=new HashMap<>();public UdpServer(int port) throws SocketException {socket=new DatagramSocket(port);//初始化hashMaphashMap.put("你好","hello");hashMap.put("明天","tomorrow");hashMap.put("客户端","client");hashMap.put("服务器","server");}public void start() throws IOException {System.out.println("启动服务器");while(true){//1.接收用户请求DatagramPacket requestPacket=new DatagramPacket(new byte[4096],4096);socket.receive(requestPacket);//2.解析用户请求String request=new String(requestPacket.getData(),0,requestPacket.getLength());//3.根据用户请求构造响应String response=process(request);DatagramPacket responsePacket=new DatagramPacket(response.getBytes(),response.getBytes().length,requestPacket.getSocketAddress());socket.send(responsePacket);//4.打印日志String log=String.format("[%s,%d]:request:%s,response:%s",responsePacket.getAddress(),responsePacket.getPort(),request,response);System.out.println(log);}}public String process(String request){return hashMap.getOrDefault(request,"该词在词典中不存在");}public static void main(String[] args) throws IOException {UdpServer udpServer=new UdpServer(9090);udpServer.start();}
}

客户端:
在这里插入图片描述
服务器:
在这里插入图片描述

4.扩展"翻译器"

上面代码用的是HashMap,在下面的代码中,让代码连接数据库,待查词中文,去数据库中查表,查出对应的英文。

a.数据库设计

//1.数据库设计
//db.sql
create database if not exists test_2_8 ;
use test_2_8;drop table if exists translate;
create table translate (id int primary key auto_increment,chinese varchar(50),english varchar(50)
);
insert into translate values(null,"你好","hello");
insert into translate values(null,"服务器","server");
insert into translate values(null,"客户端","client");

b.针对数据表,创建数据表对象

//创建数据表对象
//+----+-----------+---------+
//        | id | chinese   | english |
//        +----+-----------+---------+
//        |  1 | 你好      | hello   |
//        |  2 | 服务器    | server  |
//        |  3 | 客户端    | client  |
//        +----+-----------+---------+
public class Translate {private int id;private String chinses;private String english;@Overridepublic String toString() {return "Translate{" +"id=" + id +", chinses='" + chinses + '\'' +", english='" + english + '\'' +'}';}public int getId() {return id;}public void setId(int id) {this.id = id;}public String getChinses() {return chinses;}public void setChinses(String chinses) {this.chinses = chinses;}public String getEnglish() {return english;}public void setEnglish(String english) {this.english = english;}
}

c.连接数据库

import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;public class Util {private static final String URL="jdbc:mysql://127.0.0.1:3306/test_2_8?characterEncoding=utf8&&useSSL=false";private static final String USERNAME="root";private static final String PASSWORD="root";static DataSource dataSource=new MysqlDataSource();public static Connection getConnection() throws SQLException {((MysqlDataSource)dataSource).setUrl(URL);((MysqlDataSource)dataSource).setUser(USERNAME);((MysqlDataSource)dataSource).setPassword(PASSWORD);return dataSource.getConnection();}public static void getClose(Connection connection, PreparedStatement statement, ResultSet resultSet){if(resultSet!=null){try {resultSet.close();} catch (SQLException throwables) {throwables.printStackTrace();}}if(statement!=null){try {statement.close();} catch (SQLException throwables) {throwables.printStackTrace();}}if(connection!=null){try {connection.close();} catch (SQLException throwables) {throwables.printStackTrace();}}}
}

d.客户端代码

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.util.Scanner;public class UdpClient {String serverIp;int serverPort;DatagramSocket socket=null;public UdpClient(String serverIp,int serverPort) throws SocketException {this.serverIp=serverIp;this.serverPort=serverPort;socket=new DatagramSocket();}public void start() throws IOException {Scanner scanner=new Scanner(System.in);while(true){System.out.println("->");//1.用户输入请求,并且构造请求String request=scanner.next();if(request.equals("exit")){System.out.println("程序退出");return;}DatagramPacket requestPacket=new DatagramPacket(request.getBytes(),request.getBytes().length,InetAddress.getByName(serverIp),serverPort);//2.将请求发送服务器socket.send(requestPacket);//3.从服务器接收响应DatagramPacket responsePacket=new DatagramPacket(new byte[4096],4096);socket.receive(responsePacket);String response=new String(responsePacket.getData(),0,responsePacket.getLength());//4.打印日志String log=String.format("[%s,%d]:request:%s,response:%s",responsePacket.getAddress(),responsePacket.getPort(),request,response);System.out.println(log);}}public static void main(String[] args) throws IOException {UdpClient udpClient=new UdpClient("127.0.0.1",9090);udpClient.start();}
}

e.服务器代码

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;//服务器
public class UdpServer {DatagramSocket socket=null;public UdpServer(int port) throws SocketException {socket=new DatagramSocket(port);}public void start() throws IOException {System.out.println("启动服务器");while(true){//1.接收请求DatagramPacket requestPacket=new DatagramPacket(new byte[4096],4096);socket.receive(requestPacket);//2.解析请求String request=new String(requestPacket.getData(),0,requestPacket.getLength());//3.构造响应String response=process(request);DatagramPacket responsePacket=new DatagramPacket(response.getBytes(),response.getBytes().length,requestPacket.getSocketAddress());//4.给客户端发送响应socket.send(responsePacket);//打印日志String log=String.format("[%s,%d]:request:%s,response:%s",responsePacket.getAddress(),responsePacket.getPort(),request,response);System.out.println(log);}}public String process(String request){Connection connection=null;PreparedStatement preparedStatement=null;ResultSet resultSet=null;Translate translate=new Translate();try{connection=Util.getConnection();String sql="select * from translate where chinese=?";preparedStatement=connection.prepareStatement(sql);preparedStatement.setString(1,request);resultSet=preparedStatement.executeQuery();if(resultSet.next()){translate.setEnglish(resultSet.getString("english"));}else{String t=new String("词典中不存在该词");return t;}}catch(SQLException e){e.printStackTrace();}finally {Util.getClose(connection,preparedStatement,resultSet);}return translate.getEnglish();}public static void main(String[] args) throws IOException {UdpServer server=new UdpServer(9090);server.start();}
}

结果展示:
数据库:
在这里插入图片描述
客户端:在这里插入图片描述

服务器:
在这里插入图片描述

四、TCP流套接字

1.ServerSocket
2.Socket

2.写一个回显服务器
a.客户端

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;//客户端
public class TcpEchoClient02 {Socket socket=null;String serverIp;int serverPort;public TcpEchoClient02(String serverIp,int serverPort) throws IOException {this.serverIp=serverIp;this.serverPort=serverPort;socket=new Socket(serverIp,serverPort);}public void start(){Scanner in=new Scanner(System.in);System.out.println("客户端");try(InputStream inputStream=socket.getInputStream();OutputStream outputStream=socket.getOutputStream()){while(true){System.out.println("->");String request=in.next();//将用户需求发送给服务器PrintWriter printWriter=new PrintWriter(outputStream);printWriter.println(request);printWriter.flush();//接收服务器发送的响应Scanner scanner=new Scanner(inputStream);if(!scanner.hasNext()){break;}String response=scanner.next();//打印日志String log=String.format("[%s,%d]:request:%s,response:%s",socket.getInetAddress(),socket.getPort(),request,response);System.out.println(log);}} catch (IOException e) {e.printStackTrace();}finally {try {socket.close();} catch (IOException e) {e.printStackTrace();}}}public static void main(String[] args) throws IOException {TcpEchoClient02 tcpEchoClient02=new TcpEchoClient02("127.0.0.1",9090);tcpEchoClient02.start();}
}

b.服务器

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;//服务器
public class TcpEchoServer02 {ServerSocket listenSocket=null;public TcpEchoServer02(int port) throws IOException {listenSocket=new ServerSocket(port);}public void start() throws IOException {System.out.println("启动服务器");while (true){Socket socket=listenSocket.accept();processConnection(socket);}}public void processConnection(Socket socket){String log2=String.format("[%s,%d]",socket.getInetAddress(),socket.getPort());System.out.println(log2+"服务器连接成功");try(InputStream inputStream=socket.getInputStream();OutputStream outputStream=socket.getOutputStream()){while(true){Scanner scanner=new Scanner(inputStream);if(!scanner.hasNext()){String log=String.format("[%s,%d]",socket.getInetAddress(),socket.getPort());System.out.println(log+"客户端下线");break;}String request=scanner.next();String response=process(request);PrintWriter printWriter=new PrintWriter(outputStream);printWriter.println(response);printWriter.flush();//打印日志String log=String.format("[%s,%d]:request:%s,response:%s",socket.getInetAddress(),socket.getPort(),request,response);System.out.println(log);}} catch (IOException e) {e.printStackTrace();}finally {try {socket.close();} catch (IOException e) {e.printStackTrace();}}}public String process(String request){return request;}public static void main(String[] args) throws IOException {TcpEchoServer02 tcpEchoServer02=new TcpEchoServer02(9090);tcpEchoServer02.start();}
}

结果展示:
客户端:
在这里插入图片描述
服务器:
在这里插入图片描述

上面的代码存在一个问题:
在同一时间只能支持一个客户端去访问一个服务器。
如果想要代码实现在同一时间内多个客户端访问一个服务器,该如何实现呢?
引入 多进程
只需要修改服务器代码模块

多线程下的服务器代码

idea编译器端默认一个类只能启动一次,多个客户端需要多次启动客户端代码,所以,需要更改编译器的设置:
在这里插入图片描述
在这里插入图片描述

多线程—服务器端的代码:

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;//多线程回显服务器
public class TcpThreadEchoServer {ServerSocket listenSocket=null;public TcpThreadEchoServer(int port) throws IOException {listenSocket=new ServerSocket(port);}public void start() throws IOException {System.out.println("启动服务器");while(true){Socket clientSocket=listenSocket.accept();Thread t=new Thread(){@Overridepublic void run(){processConnection(clientSocket);}};t.start();}}public void processConnection(Socket clientSocket){String log=String.format("[%s,%d]",clientSocket.getInetAddress(),clientSocket.getPort());System.out.println(log+"客户端上线");try(InputStream inputStream=clientSocket.getInputStream();OutputStream outputStream=clientSocket.getOutputStream()){while(true){Scanner scanner=new Scanner(inputStream);if(!scanner.hasNext()){log=String.format("[%s,%d]",clientSocket.getInetAddress(),clientSocket.getPort());System.out.println(log+"下线");break;}String request=scanner.next();String response=process(request);PrintWriter printWriter=new PrintWriter(outputStream);printWriter.println(response);printWriter.flush();log=String.format("[%s,%d]:request:%s,response:%s",clientSocket.getInetAddress(),clientSocket.getPort(),request,response);System.out.println(log);}} catch (IOException e) {e.printStackTrace();}}public String process(String request){return request;}public static void main(String[] args) throws IOException {TcpThreadEchoServer tcpThreadEchoServer=new TcpThreadEchoServer(9090);tcpThreadEchoServer.start();}
}

上面代码涉及到线程的创建和销毁,频繁的创建和销毁线程,开销会比较大,所以,引入了线程池.
服务器端的代码需要进行改变

线程池—服务器端的代码

//线程池---回显服务器
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 TcpThreadPoolServer {ServerSocket listenSocket=null;public TcpThreadPoolServer(int port) throws IOException {listenSocket=new ServerSocket(port);}public void start() throws IOException {System.out.println("启动服务器");while (true) {Socket socket=listenSocket.accept();//--------------------线程池---------------------------ExecutorService executorService= Executors.newCachedThreadPool();executorService.submit(new Runnable(){@Overridepublic void run(){processConnection(socket);}});}}public void processConnection(Socket socket){String log=String.format("【%s,%d】:客户端上线了",socket.getInetAddress(),socket.getPort());System.out.println(log);try(InputStream inputStream=socket.getInputStream();OutputStream outputstream=socket.getOutputStream()){while(true){Scanner scanner=new Scanner(inputStream);if(!scanner.hasNext()){log=String.format("[%s,%d]",socket.getInetAddress(),socket.getPort());System.out.println(log+"客户下线");break;}String request=scanner.next();String response=process(request);PrintWriter printWriter=new PrintWriter(outputstream);printWriter.println(response);printWriter.flush();log=String.format("[%s,%d]:request:%s,response:%s",socket.getInetAddress(),socket.getPort(),request,response);System.out.println(log);}} catch (IOException e) {e.printStackTrace();}finally {try {socket.close();} catch (IOException e) {e.printStackTrace();}}}public String process(String request){return request;}public static void main(String[] args) throws IOException {TcpThreadPoolServer tcpThreadPoolServer=new TcpThreadPoolServer(9090);tcpThreadPoolServer.start();}
}

结果:客户端1:
在这里插入图片描述

客户端2:
在这里插入图片描述
服务器:
在这里插入图片描述

场景:在某些时刻,服务器会收到很多个请求,服务器收到多个请求,需要创建多个线程,当请求过多的时候,服务器资源(eg:CPU,内存资源)不够用,服务器最后会崩溃。该如何解决在某些时刻,服务器收到多个请求这种场景呢?
1.引入协程。协程比线程更轻量;
2.IO多路复用;
3.引入多个服务器。

3.利用tcp流套接字写一个"翻译器"–“汉译英”—连接数据库

数据库和数据表的创建,和上面基于UDP的套接字实现方法是一样的。
只是客户端和服务器端的socket不一样。

a.客户端代码

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;//翻译器--客户端
public class TcpClient {Socket socket=null;String serverIp;int port;public TcpClient(String serverIp,int port) throws IOException {this.serverIp=serverIp;this.port=port;socket=new Socket(serverIp,port);}public void start(){Scanner in=new Scanner(System.in);try(InputStream inputStream=socket.getInputStream();OutputStream outputStream=socket.getOutputStream()){while(true){System.out.println("->");String request=in.next();if(request.equals("exit")){break;}PrintWriter printWriter=new PrintWriter(outputStream);printWriter.println(request);printWriter.flush();Scanner scanner=new Scanner(inputStream);if(!scanner.hasNext()){break;}String response=scanner.next();String log=String.format("【%s,%d】:request:%s,response:%s",socket.getInetAddress(),socket.getPort(),request,response);System.out.println(log);}} catch (IOException e) {e.printStackTrace();}}public static void main(String[] args) throws IOException {TcpClient tcpClient=new TcpClient("127.0.0.1",9090);tcpClient.start();}
}

b.服务器端代码

import test0209.util.DBUtil;
import test0209.util.Translate;import javax.xml.transform.Result;
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.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;//翻译器--服务器
public class TcpServer {ServerSocket listenSocket=null;public TcpServer(int port) throws IOException {listenSocket=new ServerSocket(port);}public void start() throws IOException {System.out.println("启动服务器");while(true){Socket socket=listenSocket.accept();ExecutorService executorService= Executors.newCachedThreadPool();executorService.submit(new Runnable() {@Overridepublic void run() {processConnection(socket);}});}}public void processConnection(Socket socket){String log=String.format("[%s,%d]",socket.getInetAddress(),socket.getPort());System.out.println(log+"客户端上线");try(InputStream inputStream=socket.getInputStream();OutputStream outputStream=socket.getOutputStream()){while(true){Scanner scanner=new Scanner(inputStream);if(!scanner.hasNext()){log=String.format("[%s,%d]",socket.getInetAddress(),socket.getPort());System.out.println(log+"客户端下线");break;}String request=scanner.next();String response=process(request);PrintWriter printWriter=new PrintWriter(outputStream);printWriter.println(response);printWriter.flush();log=String.format("[%s,%d]:request:%s,response:%s",socket.getInetAddress(),socket.getPort(),request,response);System.out.println(log);}} catch (IOException e) {e.printStackTrace();}}//翻译器public String process(String request){Connection connection=null;PreparedStatement preparedStatement=null;ResultSet resultSet=null;try {connection=DBUtil.getConnection();String sql="select * from translate where chinese=?";preparedStatement=connection.prepareStatement(sql);preparedStatement.setString(1,request);resultSet=preparedStatement.executeQuery();if(!resultSet.next()){String log=new String("词典中不存在该词语");return log;}Translate translate=new Translate();translate.setEnglish(resultSet.getString("english"));return translate.getEnglish();} catch (SQLException throwables) {throwables.printStackTrace();}return new String("没有查到");}public static void main(String[] args) throws IOException {TcpServer tcpServer=new TcpServer(9090);tcpServer.start();}
}

结果截图:
客户端1:
在这里插入图片描述
客户端2:
在这里插入图片描述

服务器:
在这里插入图片描述

http://www.lryc.cn/news/1827.html

相关文章:

  • 手写JavaScript中的call、bind、apply方法
  • JAVA练习46-将有序数组转换为二叉搜索树
  • linux(centos7.6)docker
  • 微信小程序滚动穿透问题
  • 安全—06day
  • PostgreSQL入门
  • 自媒体人都在用的免费音效素材网站
  • Java数据结构中二叉树的深度解析及常见OJ题
  • 算法顶级比赛汇总
  • Android MVI框架搭建与使用
  • 第九节 使用设备树实现RGB 灯驱动
  • Ubuntu 系统下Docker安装与使用
  • DHCP安全及防范
  • 【流畅的python】第一章 Python数据模型
  • from文件突然全部变为类cs右击无法显示设计界面
  • 使用arthas中vmtool命令查看spring容器中对象的某个属性
  • 四种幂等性解决方案
  • 【Nacos】Nacos配置中心客户端配置更新源码分析
  • 按钮防抖与节流-vue2
  • PyTorch学习笔记:nn.SmoothL1Loss——平滑L1损失
  • 2年时间,涨薪20k,想拿高薪还真不能老老实实的工作...
  • Spark - Spark SQL中RBO, CBO与AQE简单介绍
  • NeurIPS/ICLR/ICML AI三大会国内高校和企业近年中稿量完整统计
  • Android IO 框架 Okio 的实现原理,到底哪里 OK?
  • 一文讲解Linux 设备模型 kobject,kset
  • linux配置密码过期的安全策略(/etc/login.defs的解读)
  • c_character_string 字符串----我认真的弄明白了,也希望你们也是。
  • spring面试题 一
  • C++中char *,char a[ ]的特殊应用
  • 【Windows10】电脑副屏无法调节屏幕亮度?解决方法