【网络~】

news2024/11/26 20:48:07

网络

  • 一级目录
    • 二、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);
        //初始化hashMap
        hashMap.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;

    @Override
    public 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(){
                @Override
                public 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(){
                @Override
                public 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() {
                @Override
                public 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.coloradmin.cn/o/336224.html

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

相关文章

He3 更新:中文

系统级更新 焕然一新的主界面 这一次对整体 UI 界面做了一个大的调整&#xff0c;整体更加扁平美观&#xff0c;布局更加紧凑协调&#xff0c;视觉层面更加集中聚焦。 旧版 新版 工具内容居中 上下文工具以及关联工具放置在右侧&#xff0c;工具内容居中&#xff0c;在使…

ASP.NET Core3.1实战教程---基于Jquery单文件上传

这个必须记录一下费劲啊&#xff01;废了我2天的时间&#xff0c;昔日的net快速已经没落....就文件上传都这么费劲。 先说下要求&#xff08;在线apk文件上传实现手机端整包更新&#xff09;&#xff1a; 1、为了简化需求文件上传和数据提交分开执行 2、选完文件后按钮变成上…

web前端——HTML+CSS

整体框架 HTML CSS CSS进阶 CSS盒子模型 定位装饰 CSS精灵图 目录 基础认识 HTML 一、HTML概念 二、HTML页面固定结构 三、HTML标签的结构 四、标签学习 1、排版标签 1&#xff09;标题标签 2&#xff09;段落标签 3&#xff09;换行标签 4&#xff09;水平线…

【LeetCode】1223. 掷骰子模拟

1223. 掷骰子模拟 题目描述 有一个骰子模拟器会每次投掷的时候生成一个 1 到 6 的随机数。 不过我们在使用它时有个约束&#xff0c;就是使得投掷骰子时&#xff0c;连续 掷出数字 i 的次数不能超过 rollMax[i]&#xff08;i 从 1 开始编号&#xff09;。 现在&#xff0c;…

第八节 Linux 设备树

Linux3.x 以后的版本才引入了设备树&#xff0c;设备树用于描述一个硬件平台的板级细节。在早些的linux内核&#xff0c;这些“硬件平台的板级细节”保存在linux 内核目录“/arch”&#xff0c;以ARM 平台为例“硬件平台的板级细节”保存在“/arch/arm/plat-xxx”和“/arch/arm…

python面试准备之--算法一

文章目录时间复杂度空间复杂度递归汉诺塔问题&#xff08;递归实例&#xff09;查找列表查找顺序查找&#xff08;Linear Search&#xff09;二分查找排序列表排序冒泡排序(Bubble Sort)选择排序插入排序快速排序堆排序归并排序希尔排序计数排序基数排序时间复杂度 时间复杂度是…

机器(深度)学习中的 Dropout

在这篇文章[1]中&#xff0c;我将主要讨论神经网络中 dropout 的概念&#xff0c;特别是深度网络&#xff0c;然后进行实验&#xff0c;通过在标准数据集上实施深度网络并查看 dropout 的影响&#xff0c;看看它在实践中实际影响如何。 1. Dropout是什么&#xff1f; ★ 术语“…

迷宫最短路径【Java实现】

题目描述 现有一个n∗m大小的迷宫&#xff0c;其中1表示不可通过的墙壁&#xff0c;0表示平地。每次移动只能向上下左右移动一格&#xff0c;且只能移动到平地上。假设左上角坐标是(1,1)&#xff0c;行数增加的方向为x增长的方向&#xff0c;列数增加的方向为y增长的方向&#…

Protocol Buffers V3语法全解

目录protobuf介绍protobuf使用protoc命令语法定义消息类型指定字段类型分配字段编号指定字段规则添加更多消息类型注释保留字段从.proto文件生成了什么&#xff1f;值类型默认值枚举使用其他消息类型导入定义嵌套类型更新消息类型未知字段any任意类型oneofoneof 特性兼容性问题…

awk命令

一.介绍 awk是专门为文本处理设计的编程语言&#xff0c;是一门数据驱动的编程语言。与sed类似&#xff0c;都是以数据驱动的行处理软件&#xff0c;主要用于数据扫描&#xff0c;过滤和汇总。数据可以来自于标准输入&#xff0c;管道或者文件。 二.语法 awk是一种处理文本文件…

Vite+Vue3实现版本更新检查,实现页面自动刷新

ViteVue3实现版本更新检查&#xff0c;实现页面自动刷新1、使用Vite插件打包自动生成版本信息2、Vite.config.ts配置3、配置环境变量4、路由配置现有一个需求就是实现管理系统的版本发版&#xff0c;网页实现自动刷新页面获取最新版本 搜索了一下&#xff0c;轮询的方案有点浪费…

Mysql:避免重复的插入数据方法汇总

最常见的方式就是为字段设置主键或唯一索引&#xff0c;当插入重复数据时&#xff0c;抛出错误&#xff0c;程序终止&#xff0c;但这会给后续处理带来麻烦&#xff0c;因此需要对插入语句做特殊处理&#xff0c;尽量避开或忽略异常&#xff0c;下面我介绍4种方法&#xff1a; …

【Windows10】电脑副屏无法调节屏幕亮度?解决方法

先说下情况&#xff0c;本人对显示器不太懂&#xff0c;属于小白 这个副屏无法调节的问题出现也已经很久了&#xff0c;但是之前亮度适合就无所谓&#xff0c;今天突然按了之后很亮&#xff0c;于是就找问题。 第一步&#xff0c;我直接百度&#xff0c;遇事不决&#xff0c;百…

59 双向循环神经网络【动手学深度学习v2】

59 双向循环神经网络【动手学深度学习v2】 深度学习学习笔记 学习视频&#xff1a;https://www.bilibili.com/video/BV12X4y1c71W/?spm_id_fromautoNext&vd_source75dce036dc8244310435eaf03de4e330 核心思想&#xff1a;取决于过去和未来的上下文&#xff0c;来预测当前的…

Apache Spark 命令注入(CVE-2022-33891)

利用范围 Spark Core - Apache <3.0.3 3.1.1 < Spark Core - Apache <3.1.2 3.2.0 < Spark Core - Apache <3.2.1 环境搭建 修改bin目录下的spark-shell 修改如下&#xff0c;添加调试端口 变动如上 然后启动 ./spark-shell --conf spark.acls.enabletrue即…

使用百度地图官方WEB API,提示 “ APP 服务被禁用“ 问题的解决方法

问题描述 项目上用了百度地图官方WEB API&#xff0c;打开界面时百度地图无法打开&#xff0c;出现弹窗&#xff1a; APP被您禁用啦。详情查看&#xff1a;http://lbsyun.baidu.com/apiconsole/key#。 原因分析&#xff1a; 查看错误信息&#xff1a;"status":240,…

Word文档带有权限密码怎么办?

Word文档的权限密码指的是什么&#xff1f;其实这是Word文档的保护方法之一&#xff0c;具体指Word文档的编辑、修改受到了限制&#xff0c;需要输入密码才能进行。 设置了权限密码的Word文档还是可以直接打开&#xff0c;只有当需要编辑或者修改内容的时候&#xff0c;才会发…

CSDN版的详细MarkDown的使用教程

MarkDown的使用欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释…

雅思经验(7)

我发现雅思阅读要命的不是难度&#xff0c;而是时间的把控。考试时间是总共一小时&#xff0c;但是要写三篇文章&#xff0c;之后总共40道题目&#xff0c;也就是说每篇文章平均是13.3道。但是他们很多人说&#xff0c;如果誊写答案需要花掉3、4分钟每篇&#xff0c;也就是说真…

学习IB课程的宝藏网站,有需求选择

很多学习IB课程的同学都会觉得IB课程很难&#xff0c;平时作业很多根本没时间找资料&#xff0c;其实不用担心&#xff0c;关于IB课程学习的网站&#xff0c;小编已经帮大家整理好了&#xff0c;建议收藏起来&#xff01; 数学类IB网站&#xff1a;Revision Villag 数学对于会的…