0
点赞
收藏
分享

微信扫一扫

9. Spring Boot 日志文件

吓死我了_1799 04-16 10:30 阅读 1

目录

🚩TCP流套接字编程

🍭ServerSocket API

🍭Socket API

🍭TCP服务器

🍭TCP客户端


🚩TCP流套接字编程


🍭ServerSocket API

ServerSocket 是创建 TCP 服务端 Socket API

ServerSocket 构造方法:

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

ServerSocket 方法:

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

🍭Socket API

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

不管是客户端还是服务端 Socket ,都是双方建立连接以后,保存的对端信息,及用来与对方收发数据的。

Socket 构造方法:

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

Socket方法:

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

TCP是有连接的,连接就意味着通信双方会记录保存对端的信息,UDP来说,每次发送数据都得手动send方法中指定目标地址(UDP自身没有存储这个消息)TCP来说,则不需要,前提是需要先把连接给建立上。那么,如果建立连接呢?不需要代码干预,是系统内核自动负责完成的,对应app来说,客户端这边,主要是要发起”建立连接"动作,服务器这边,主要要把建立好的连接从内核中拿到app里。


TCP中用ServerSocket (给服务器使用的类,使用这个类来绑定端口号),服务器启动之后用到accept方法,把内核中建立好的连接到应用程序中去(建立连接的过程是内核自动完成的,应用程序是捡漏的),如果没有与客户端连接,那么就阻塞等待。

  private ServerSocket serverSocket=null;

    public TCPEchoServer(int port) throws IOException {
        serverSocket =new ServerSocket(port);
    }

    public void start() throws IOException {
        System.out.println("服务器正式启动");
        while (true){
            //通过accpet方法,把内核中已经建立好的连接拿到app中
            //建立连接的细节流程都是内核自动完成的,app只需要“捡现成”的
            Socket clientSocket=serverSocket.accept();
        }
    }

在销售A卖楼盘的时候,销售在路上看到一个人想找一个人问问需不需要买房,然后那个男生就带去楼盘区,然后销售找了一个专业的置业顾问B,来介绍楼盘。而这个销售就去路上继续找人。

A:在外面招揽客人

B:给客人提供详细的服务

然后我们调用方法来处理当前的连接。首先我们先打印一个日志,表示已经与客户端建立连接了。

 //打印这个日志,来表示客户端连上了
        System.out.printf("[%s:%d] 客户端上线!\n",clientSocket.getInetAddress(),clientSocket.getPort());

 Scanner scanner=new Scanner(inputStream);
 //1.读取请求并解析,此处就以next来作为读取请求的方式,.next的规则是,读到“空白符”就返回
   String request=scanner.next();
 //2.根据请求,计算响应
   String response=process(request);
//3.把响应写回客户端
 //可以把String转成字节数组,写入到OutputStream,
//也可以使用PrintWriter把OutputStream包裹一下,来写入字符串
   PrintWriter printWriter=new PrintWriter(outputStream);
//此处的println不是打印到控制台了,而是写入到outputStream对应的流对象,也就是写入到clientSocket
//自然这个数据也就通过网络发送出去了,
 //此处使用println带有\n 也是为了后续 客户端这边 可以使用 scanner.next来读取数据
     printWriter.write(response);

空白符 是一类特殊的字符,换行,回车符,空格,制表符,翻页符,垂直制表符


🍭TCP服务器

package TCP;

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 TCPEchoServer {
    private ServerSocket serverSocket=null;

    public TCPEchoServer(int port) throws IOException {
        serverSocket =new ServerSocket(port);
    }

    public void start() throws IOException {
        System.out.println("服务器正式启动");
        while (true){
            //通过accpet方法,把内核中已经建立好的连接拿到app中
            //建立连接的细节流程都是内核自动完成的,app只需要“捡现成”的
            Socket clientSocket=serverSocket.accept();
           Thread t=new Thread(()->{
                processConnection(clientSocket);
            });
           t.start();
        }
    }
    //通过这个方法,来处理当前的连接
    public void processConnection(Socket clientSocket) {
        //打印这个日志,来表示客户端连上了
        System.out.printf("[%s:%d] 客户端上线!\n",clientSocket.getInetAddress(),clientSocket.getPort());
        try(InputStream inputStream=clientSocket.getInputStream();
            OutputStream outputStream=clientSocket.getOutputStream()) {
            //使用try()方式,避免后续用完了流对象,忘记关闭
            //由于客户端发来的数据,可能是"多条数据“,针对多条数据,就循环处理
            while (true){
                Scanner scanner=new Scanner(inputStream);
                if(!scanner.hasNext()){
                    //连接断开了,此时循环就应该结束
                    System.out.printf("[%s:%d] 客户端下线!\n",clientSocket.getInetAddress(),clientSocket.getPort());
                    break;
                }
                //1.读取请求并解析,此处就以next来作为读取请求的方式,.next的规则是,读到“空白符”就返回
                String request=scanner.next();
                //2.根据请求,计算响应
                String response=process(request);
                //3.把响应写回客户端
                //可以把String转成字节数组,写入到OutputStream,
                //也可以使用PrintWriter把OutputStream包裹一下,来写入字符串
                PrintWriter printWriter=new PrintWriter(outputStream);
                //此处的println不是打印到控制台了,而是写入到outputStream对应的流对象,也就是写入到clientSocket
                //自然这个数据也就通过网络发送出去了,
                //此处使用println带有\n 也是为了后续 客户端这边 可以使用 scanner.next来读取数据
                printWriter.println(response);
                //此处还要记得有个操作,刷新缓冲区,如果没有刷新操作,可能数据仍然是在内存中,没有被写入网卡
                printWriter.flush();
                //打印了这次请求交互过程的内容
                System.out.printf("[%s:%d] req=%s resp=%s\n",clientSocket.getInetAddress(),clientSocket.getPort(),request,response);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }finally {
            //进行clientSocket的关闭
            try {
                clientSocket.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
    public String process(String request){
        return request;
    }
    public static void main(String[] args) throws IOException {
        TCPEchoServer tcpEchoServer=new TCPEchoServer(9090);
        tcpEchoServer.start();
    }
}

如果我们出现了多个客户端连接同一个服务器该怎么办呢?这就考虑到多线程的知识了,如果有客户端就开启线程。


🍭TCP客户端

  private Socket socket=null;
    public TCPClient(String serverIP, int serverPort) throws IOException {
        //需要在创建Socket的同时,和服务器”建立连接“ 此时就得告诉Socket服务器在哪里
        //具体建立连接的细节,不需要咱们代码手动干预,是内核自动负责的
        //当我们new这个对象的时候,操作系统内核,就开始使用 三次握手 具体细节 完成建立连接的过程
        socket =new Socket(serverIP,serverPort);
    }
package TCP;

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 {
    private Socket socket=null;
    public TCPClient(String serverIP, int serverPort) throws IOException {
        //需要在创建Socket的同时,和服务器”建立连接“ 此时就得告诉Socket服务器在哪里
        //具体建立连接的细节,不需要咱们代码手动干预,是内核自动负责的
        //当我们new这个对象的时候,操作系统内核,就开始使用 三次握手 具体细节 完成建立连接的过程
        socket =new Socket(serverIP,serverPort);
    }

    public void start(){
        System.out.println("客户端启动");
        //tcp客户端行为和udp客户端差不多
        //从服务器读取响应
        //把响应显示到界面上
        Scanner scanner=new Scanner(System.in);
        try(InputStream inputStream=socket.getInputStream();
            OutputStream outputStream=socket.getOutputStream()) {
            Scanner scanner1=new Scanner(inputStream);
            while (true){
                //1.从控制台输入内容
                System.out.println("->");
                String request=scanner.next();
                //2.把字符串作为请求,发送给服务器
                PrintWriter printWriter=new PrintWriter(outputStream);
                printWriter.println(request);
                printWriter.flush();
                //3.读取服务器返回的响应
                String response=scanner1.next();
                //4.界面显式内容
                System.out.println(response);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static void main(String[] args) throws IOException {
        TCPClient tcpClient=new TCPClient("172.20.10.2",9090);
        tcpClient.start();
    }
}

举报

相关推荐

0 条评论