端午节学习<网络编程套接字socket>贼cool好吧

27 篇文章 4 订阅
10 篇文章 2 订阅

本章要点

  • 学会socket api原理
  • 熟悉TCPUDP服务器客户端的编写!

概念

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

网络编程套接字,是操作系统给应用程序提供的一组API(socket API)!

在这里插入图片描述
socket原意插座!
是传输层和应用层通信的桥梁!
我们调用操作系统的Socket的方法就可通信到传输层!
而我们知道传输层的协议有两种TCP/UDP!
所以socket也提供了两组API用于不同协议点网络编程!

TCP/UDP区别
由于TCP/UDP两组协议相差较大!因而socket下对应的API也差很多!
我们再来介绍一下TCP/UDP协议的特点!

TCPUDP
有连接无连接
可靠传输不可靠传输
面向字节流面向数据报
全双工全双工

我们分别介绍一下上述的特点是什么意思!
有连接
有连接就是相当于接电话,需要接通后,才能进行消息传递,不想微信/QQ不要接通就可以发消息!
可靠传输
可靠传输就是我们知道我们当前传输的数据对方是否收到了!就类型于钉钉和淘宝的已读功能!如果我们不知道对方是否收到了,那就是不可靠传输!
这里的可靠并不是传统意义的可靠(和数据是否丢失或者盗窃并么有关系)!
面向字节流
面向字节流传输就是,以字节的为单位进行传输,而面向数据报是以数据报为单位进行传输,一个数据报可能为多个字节,只能传输单位个数据报!

全双工
全双工就是一条链路,双向通信,半双工,就是一条链路,单向通信!

UDP数据报套接字编程

我们先来了解一下UDP协议在socket对应的API~
我们进行网络编程需要用到的类都在java.net包下!
在这里插入图片描述

我们UDP socket 编程主要涉及到下面来个类:
在这里插入图片描述

  • DatagramPacket
  • DatagramSocket
    我们来学习下这两个类中的一些重要方法:

DatagramPacket 该类表示数据报包

数据报包用于实现无连接分组传送服务。 仅基于该数据包中包含的信息,每个消息从一台机器路由到另一台机器。 从一台机器发送到另一台机器的多个分组可能会有不同的路由,并且可能以任何顺序到达。 包传送不能保证。

UDP网络编程等下可能要用到的方法:

构造方法:
在这里插入图片描述
通过上述的构造方法我们可以创建不同类型的数据报,有用于接收数据的数据报,还有进行发送数据的数据报!

接收数据的数据报:

  • DatagramPacket(byte[] buf, int length)
    构造一个 DatagramPacket用于接收长度的数据包 length
  • DatagramPacket(byte[] buf, int offset, int length)
    构造一个 DatagramPacket用于接收长度的分组 length ,指定偏移到缓冲器中。

上面的两种构造方式都是用于接收数据!相当于一个已经设置好容量的空盘子!
buf字节数组,确定字节容量!
length 可以存放多大的字节长度
offset从偏移量位置开始存储

发送数据的数据报

  • DatagramPacket(byte[] buf, int length, InetAddress address, int port)
    构造用于发送长度的分组的数据报包 length指定主机上到指定的端口号。

  • DatagramPacket(byte[] buf, int offset, int length, InetAddress address, int port)
    构造用于发送长度的分组数据报包 length具有偏移 ioffset指定主机上到指定的端口号。

  • DatagramPacket(byte[] buf, int offset, int length, SocketAddress address)
    构造用于发送长度的分组数据报包 length具有偏移 ioffset指定主机上到指定的端口号。

  • DatagramPacket(byte[] buf, int length, SocketAddress address)
    构造用于发送长度的分组的数据报包 length指定主机上到指定的端口号。

可以看到用于发送数据报的构造方法,要传入,IPport端口号等信息才知道这个数据报该发给那个客户端!
InetAddress IP地址
port 端口号
SocketAddress:包含了IP和端口号

DatagramSocket 此类表示用于发送和接收数据报数据包的套接字。

数据报套接字是分组传送服务的发送或接收点。 在数据报套接字上发送或接收的每个数据包都被单独寻址和路由。 从一个机器发送到另一个机器的多个分组可以不同地路由,并且可以以任何顺序到达。

构造方法 在这里插入图片描述

  • DatagramSocket()
    构造数据报套接字并将其绑定到本地主机上的任何可用端口。
  • DatagramSocket(DatagramSocketImpl impl)
    使用指定的DatagramSocketImpl创建一个未绑定的数据报套接字。
  • DatagramSocket(int port)
    构造数据报套接字并将其绑定到本地主机上的指定端口。
  • DatagramSocket(int port, InetAddress laddr)
    创建一个数据报套接字,绑定到指定的本地地址。
  • DatagramSocket(SocketAddress bindaddr)
    创建一个数据报套接字,绑定到指定的本地套接字地址。

我们可以传入IP地址和端口号,让该服务器或者客户端绑定该IP或者该端口号!
也可以无参,由系统分配端口号!

上面这两个类中还有许多常用方法,我们使用到的时候再介绍!

UDP数据报套接字编程案例

  • 回显服务客户端和服务器

我们通过UDP socket 实现一个回显服务的服务器和客户端,就是客户端给服务器发信息,服务器会转发刚刚发送的信息给客户端!
通过这个案例,可以学习UDP网络编程的流程!

//回显服务器代码
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class UdpEchoServer {
    //1.源端口 服务器的端口号 需要自己设置
    //2.源IP 服务器主机的IP
    //3.目的端口 客户端的端口号 服务器接收的数据报中有
    //4.目的IP 客户端IP 服务器接收的数据报中!
    //5.协议类型 UDP

    //编程前提 创建socket实例 用于操作系统中的socket api
     DatagramSocket socket = null;
    public UdpEchoServer(int port) throws SocketException { //设置服务器的端口号
        socket = new DatagramSocket(port);
    }
    //启动服务器
    public void start() throws IOException {
        System.out.println("启动服务器!");
        //UDP不需要建立连接,直接接收请求即可!
        while (true){
            //为了接收数据 创建了一个指定空间大小的空数据报!
            DatagramPacket requestPacket = new  DatagramPacket(new byte[1024],1024);
            socket.receive(requestPacket);//输出型参数 //request 就接收到了数据!
            //获取请求,将数据报转化成字符串!
            //指定获取数据的起始位置和长度还有编码格式
            String request = new String(requestPacket.getData(),0,requestPacket.getLength(),"UTF-8");
            //根据请求计算响应
            String response = process(request);
            //将响应封装成数据报
            //转化成字节数组,字节大小,目的端口和地址getSocktAddress!
            DatagramPacket responsePacket = new DatagramPacket(response.getBytes(),response.getBytes().length,requestPacket.getSocketAddress());
            socket.send(responsePacket);
            //将客户端的ip 端口 请求 响应 打印
            System.out.printf("[%s,%d] req:%s res:%s\n",requestPacket.getAddress(),requestPacket.getPort(),request,response);
        }
    }

    public String  process(String request) {
        //回显服务,直接返回请求
        return  request;
    }

    public static void main(String[] args) throws IOException {
        UdpEchoServer udpEchoServer = new UdpEchoServer(9090); //设置服务器端口 9090
        udpEchoServer.start(); //启动服务器!
    }
}

//回显客户端代码
import java.io.IOException;
import java.net.*;
import java.util.Scanner;
public class UdpEchoClient {
    //1.源IP 客户端本机IP
    //2.源端口 客户端端口 可以由系统随机分配
    //3.目的IP 服务器IP
    //4.目的端口 服务器端口
    //5.协议类型 UDP
    DatagramSocket socket= null;
    String serverIp =null;
    int serverPort = 0;
    public UdpEchoClient(String serverIp,int serverPort) throws SocketException {
        //服务器不需要指定端口,系统分配!
        socket = new DatagramSocket();
        this.serverIp = serverIp;
        this.serverPort = serverPort;
    }
    //启动客户端
    public void start() throws IOException {
        System.out.println("启动客户端");
        Scanner scanner = new Scanner(System.in);
        while(true){
            //写请求 从控制台输入字符!
            System.out.print("->");
            String request = scanner.nextLine();
            //将请求封装成数据报
            //这里需要将目的IP和端口传入! 并且需要调用InetAddress.getByName(serverIp)传入目的IP
            DatagramPacket requestPacket = new DatagramPacket(request.getBytes(),request.getBytes().length, InetAddress.getByName(serverIp),serverPort);
            //发送请求给客户端
            socket.send(requestPacket);
            //接收请求
            //给出接收请求的空数据报
            DatagramPacket responsePacket = new DatagramPacket(new byte[1024],1024);
            socket.receive(responsePacket);
            //将收到的数据报转化成字符串显示
            //起始位置,长度,编码方式
            String response = new String(responsePacket.getData(),0,responsePacket.getLength(),"UTF-8");
            //输出响应
            System.out.println("req:"+request+" res:"+response);
        }
    }

    public static void main(String[] args) throws IOException {
        //这里传入的是服务器的IP和端口号
        UdpEchoClient udpEchoClient = new UdpEchoClient("127.0.0.1",9090);
        //启动服务器
        udpEchoClient.start();
    }
}

启动服务器:
在这里插入图片描述
启动客户端:
在这里插入图片描述
我们需要先启动服务器,然后再启动客户端,因为服务器是被动接收的一方,如果客户端没有和服务器发送信息,那么服务器就会一直阻塞在 socket.receive(requestPacket)等待客户端!
在这里插入图片描述
服务器接收到端口号为57266客户端的请求,发送了响应!
在这里插入图片描述
而客户端也接收到了服务器发送的响应,实现了回显服务!

我们知道一个服务器程序一般都有多个客户端访问!
如果想要有其他的客户端访问,该如何做呢!
在这里插入图片描述
当我们再次启动客户端程序,会弹出让我们先关闭该程序的窗口!
这样就只能运行一个客户端…

当我们Allow parallel run就可以同时运行多个实例!
在这里插入图片描述
在这里插入图片描述
此时我们就有多个客户端了!
在这里插入图片描述
服务器也连接了多个客户端!
这就是实现了1对多!

  • 字典服务客户端服务器

刚刚的案例,显然没有一点技术,我可改进一下响应,写一个字典服务的服务器,支持中英翻译!

//翻译服务服务器
import java.io.IOException;
import java.net.SocketException;
import java.util.HashMap;
public class UdpDictServer extends UdpEchoServer{
    private HashMap<String,String> dict = new HashMap<>();
    public UdpDictServer(int port) throws SocketException {
        super(port);
        dict.put("cat","小猫");
        dict.put("dog","小狗");
        dict.put("pig","小猪");
        dict.put("child","小孩");
    }
    @Override
    public String process(String request) {
        //返回翻译!
        return dict.getOrDefault(request,"暂且不会");
    }

    public static void main(String[] args) throws IOException {
        UdpDictServer udpDictServer =new UdpDictServer(9090);
        udpDictServer.start();
    }
}

我们客户端并不用改变,访问该服务器就可以实现翻译的效果!
在这里插入图片描述

TCP流套接字编程

我们知道TCP是有连接的!
所以我们需要先对客户端建立连接!
我们来学习一下TCP协议对应的Socket API!

我们先来学习两个类:
通过这两个类我们就可以对TCP协议网络编程!

这两个类也在java.net包下!
在这里插入图片描述

  • ServerSocket
    这个类实现了服务器套接字。

服务器套接字等待通过网络进入的请求。 它根据该请求执行一些操作,然后可能将结果返回给请求者。
服务器套接字的实际工作由SocketImpl类的实例执行。 应用程序可以更改创建套接字实现的套接字工厂,以配置自己创建适合本地防火墙的套接字!
构造方法:
在这里插入图片描述

  • ServerSocket()
    创建未绑定的服务器套接字。
  • ServerSocket(int port)
    创建绑定到指定端口的服务器套接字。
  • ServerSocket(int port, int backlog)
    创建服务器套接字并将其绑定到指定的本地端口号,并指定了积压。
  • ServerSocket(int port, int backlog, InetAddress bindAddr)
    创建一个具有指定端口的服务器,侦听backlog和本地IP地址绑定。

我们主要用到的是第二个构造方法!我们的服务器一般都需要绑定端口号,便于客户端访问!
这个类一般用于服务器程序!

需要用到的方法
在这里插入图片描述

  • Socket accept()
    倾听要连接到此套接字并接受它!

通过这个方法,我们就可以与客户端建立连接!
返回的Socket对象,我们后面的操作就对socket对象进行就好了!
ServerSocket对象就完成了他的任务和使命了!

就好比之前的电话接线员,连接后就和他没有关系了!剩下的就交个两个打电话的人了!这里的也是剩下的就交给socket对象就好了!

用通俗的话讲就是,这里的ServerSocket就做了一件事情,通过网络请求,与客户端建立连接,执行完后就将结果返回给请求者!

  • Socket

该类实现客户端套接字(也称为“套接字”)。 套接字是两台机器之间通讯的端点。
套接字的实际工作由SocketImpl类的实例执行。 应用程序通过更改创建套接字实现的套接字工厂,可以配置自己创建适合本地防火墙的套接字。
这里的Socket对象就相当于接电话的两个人,下面的通讯操作,主要通过这个类来实现!

构造方法
在这里插入图片描述

  • Socket()
    创建一个未连接的套接字,并使用系统默认类型的SocketImpl。
  • Socket(InetAddress address, int port)
    创建流套接字并将其连接到指定IP地址的指定端口号。

我们主要学习这两个构造方法!
第一个无参构造,一般用于服务器!当ServerSocket对象调用accept方法后就可以用这个对象接收!因为这个socket对象是来自客户端,所有已经有了端口号!

而第二个构造方法一般用于创建服务器socket!
注意:

这里的addressport并不是像UDP一样设置直接的端口号,而是连接到这个IP和端口号的服务器!

需要用到的方法

  • void close()
    关闭此套接字。
  • InetAddress getInetAddress()
    返回套接字所连接的地址。
  • InetAddress getLocalAddress()
    获取套接字所绑定的本地地址。

这里一个是连接的服务器地址,一个是自己的地址!

  • int getLocalPort()
    返回此套接字绑定到的本地端口号。
  • InputStream getInputStream()
    返回此套接字的输入流。
  • OutputStream getOutputStream()
    返回此套接字的输出流。

我们上面的这两个方法就实现了TCP面向字节流!

通过操作上面的两个对象就可以实现通信,输入和输出了!

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 {
    //1.ServerSocket 只负责建立连接!
    ServerSocket serverSocket = null;
    public TcpEchoServer(int port) throws IOException {
        serverSocket = new ServerSocket(port);
    }
    public void start() throws IOException {
        System.out.println("服务器启动!");
        while(true){
            //因为TCP是有连接的,我们要先建立连接(接电话)
            //ServerSocket只做了一件事情,调用accept方法建立连接
            //我们就得到了socketClient客户!!!
            //后面就只需要针对socketClient进行操作即可!
            //如果没有客户端连接,accept就会阻塞!
            Socket socketClient = serverSocket.accept();
            processConnection(socketClient);
        }
    }

    public void processConnection(Socket socketClient) {
        //TCP面向字节流,所以直接通过文件操作,便可以将数据读写!
        try(InputStream inputStream = socketClient.getInputStream()) {
            //调用getInputStrem方法获取到请求,用输入字节流接收!
            try(OutputStream outputStream = socketClient.getOutputStream()){
                //调用getOutStrem方法,用于输出应答!
                //通过scanner读取请求更便利!
                Scanner scanner = new Scanner(inputStream);
                //循环处理每一个请求,返回对应响应!
                while(true){
                    if(!scanner.hasNext()){
                        System.out.printf("[客户端IP:%s,port:%d] 退出连接\n",socketClient.getInetAddress(),socketClient.getPort());
                        break;
                    }
                    //获取到请求
                    String request = scanner.next();
                    //根据请求给出应答
                    String response = process(request);
                    //把这个响应给客户端!
                    //通过printwiter包裹OutputSteam!
                    PrintWriter printWriter = new PrintWriter(outputStream);
                    //将请求字符串写入到输出流中!
                    printWriter.println(response);
                    printWriter.flush();//刷新缓冲器,让客户端立即获取到响应!
                    System.out.printf("[客户端IP:%s,port:%d] req:%s,res:%s\n",socketClient.getInetAddress(),socketClient.getPort(),request,response);
                }

            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                //关闭资源!
                socketClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    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.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
public class TcpEchoClient {
    private Socket socket = null;
    public TcpEchoClient(String serverIp,int serverPort) throws IOException {
        //客户端
        //这里的IP和端口是服务器的,并且这里传入IP和port表示与这个服务器建立连接!
        socket = new Socket(serverIp,serverPort);
    }
    public void start(){
        System.out.println("和服务器连接成功!");
        Scanner scanner = new Scanner(System.in);
        try(InputStream inputStream = socket.getInputStream()){
            try(OutputStream outputStream = socket.getOutputStream()){
                while(true){
                    //1.从控制台读取请求
                    System.out.print("->");
                    String request = scanner.next();
                    //2.构造请求并发送给服务器
                    PrintWriter printWriter = new PrintWriter(outputStream);
                    printWriter.println(request);
                    printWriter.flush();
                    //3.读取响应
                    Scanner scannerResponse = new Scanner(inputStream);
                    String response = scannerResponse.next();
                    //把结果打印到控制台!
                    System.out.printf("req:%s,res:%s\n",request,response);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                //关闭资源
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    public static void main(String[] args) throws IOException {
      TcpEchoClient tcpEchoClient = new TcpEchoClient("127.0.0.1",9090);
      tcpEchoClient.start();
    }
}

启动服务器:
在这里插入图片描述
启动客户端:
在这里插入图片描述
在这里插入图片描述
可以看到,这里我们也实现了回显服务!

当我们多开几个客户端试试!
在这里插入图片描述
在这里插入图片描述
可以看到客户端并没有收到应答,服务器也没和客户端建立连接!

因为,我们的ServerSocket对象,调用了accept后就一直在循环中,如果当前客户端不和服务器断开连接的话,就不会和其他客户端建立连接了!
在这里插入图片描述
我们如何才能实现多客户端呢?

我们回顾之前的对线程操作!我们可以有多个线程同时对多个客户端建立连接!!!
那我们进行升级一下变成多进程版本的服务器!

//多线程版本服务器
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{
    //1.ServerSocket 只负责建立连接!
    ServerSocket serverSocket = null;
    public TcpThreadEchoServer(int port) throws IOException {
        serverSocket = new ServerSocket(port);
    }
    public void start() throws IOException {
        System.out.println("服务器启动!");
        while(true){
            //因为TCP是有连接的,我们要先建立连接(接电话)
            //ServerSocket只做了一件事情,调用accept方法建立连接
            //我们就得到了socketClient客户!!!
            //后面就只需要针对socketClient进行操作即可!
            //如果没有客户端连接,accept就会阻塞!
            Thread thread = new Thread(()->{
                Socket socketClient = null;
                try {
                    socketClient = serverSocket.accept();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                processConnection(socketClient);
            });
           thread.start();
        }
    }
    public void processConnection(Socket socketClient) {
        //TCP面向字节流,所以直接通过文件操作,便可以将数据读写!
        try(InputStream inputStream = socketClient.getInputStream()) {
            //调用getInputStrem方法获取到请求,用输入字节流接收!
            try(OutputStream outputStream = socketClient.getOutputStream()){
                //调用getOutStrem方法,用于输出应答!
                //通过scanner读取请求更便利!
                Scanner scanner = new Scanner(inputStream);
                //循环处理每一个请求,返回对应响应!
                while(true){
                    if(!scanner.hasNext()){
                        System.out.printf("[客户端IP:%s,port:%d] 退出连接\n",socketClient.getInetAddress(),socketClient.getPort());
                        break;
                    }
                    //获取到请求
                    String request = scanner.next();
                    //根据请求给出应答
                    String response = process(request);
                    //把这个响应给客户端!
                    //通过printwiter包裹OutputSteam!
                    PrintWriter printWriter = new PrintWriter(outputStream);
                    //将请求字符串写入到输出流中!
                    printWriter.println(response);
                    printWriter.flush();//刷新缓冲器,让客户端立即获取到响应!
                    System.out.printf("[客户端IP:%s,port:%d] req:%s,res:%s\n",socketClient.getInetAddress(),socketClient.getPort(),request,response);
                }

            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                //关闭资源!
                socketClient.close();
            } 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 TcpThreadPoolEchoServer {
    //1.ServerSocket 只负责建立连接!
    ServerSocket serverSocket = null;
    public TcpThreadPoolEchoServer(int port) throws IOException {
        serverSocket = new ServerSocket(port);
    }
    public void start() throws IOException {
        System.out.println("服务器启动!");
        ExecutorService pool = Executors.newCachedThreadPool();
        while(true){
            //因为TCP是有连接的,我们要先建立连接(接电话)
            //ServerSocket只做了一件事情,调用accept方法建立连接
            //我们就得到了socketClient客户!!!
            //后面就只需要针对socketClient进行操作即可!
            //如果没有客户端连接,accept就会阻塞!

            //线程池版本!
            Socket socketClient = serverSocket.accept();
            pool.submit(new Runnable() {
                @Override
                public void run() {

                }
            });
            processConnection(socketClient);
        }
    }

    public void processConnection(Socket socketClient) {
        //TCP面向字节流,所以直接通过文件操作,便可以将数据读写!
        try(InputStream inputStream = socketClient.getInputStream()) {
            //调用getInputStrem方法获取到请求,用输入字节流接收!
            try(OutputStream outputStream = socketClient.getOutputStream()){
                //调用getOutStrem方法,用于输出应答!
                //通过scanner读取请求更便利!
                Scanner scanner = new Scanner(inputStream);
                //循环处理每一个请求,返回对应响应!
                while(true){
                    if(!scanner.hasNext()){
                        System.out.printf("[客户端IP:%s,port:%d] 退出连接\n",socketClient.getInetAddress(),socketClient.getPort());
                        break;
                    }
                    //获取到请求
                    String request = scanner.next();
                    //根据请求给出应答
                    String response = process(request);
                    //把这个响应给客户端!
                    //通过printwiter包裹OutputSteam!
                    PrintWriter printWriter = new PrintWriter(outputStream);
                    //将请求字符串写入到输出流中!
                    printWriter.println(response);
                    printWriter.flush();//刷新缓冲器,让客户端立即获取到响应!
                    System.out.printf("[客户端IP:%s,port:%d] req:%s,res:%s\n",socketClient.getInetAddress(),socketClient.getPort(),request,response);
                }

            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                //关闭资源!
                socketClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    public String process(String request) {
        //回显
        return request;
    }

    public static void main(String[] args) throws IOException {
        TcpThreadPoolEchoServer tcpThreadPoolEchoServer = new TcpThreadPoolEchoServer(9090);
        tcpThreadPoolEchoServer.start();
    }
}

我们对TCPUDP socket API网络编程的学习就到此为止,还有其他的内容,我们下次学习!

  • 37
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 58
    评论
评论 58
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bug 郭

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值