关于javascript:实现服务器和客户端数据交互Java-Socket有妙招

59次阅读

共计 5490 个字符,预计需要花费 14 分钟才能阅读完成。

本文分享自华为云社区《Java Socket 如何实现服务器和客户端数据交互》,作者:jackwangcumt。GoodMai

1 Socket 概述
依据百度百科的定义,Socket 译为套接字,它是对网络中不同主机上的利用过程之间进行双向通信的端点的形象。一个 Socket 实例就是网络上过程通信的一端,提供了应用层过程利用网络协议替换数据的机制。Socket 向上连贯各种利用过程,向下连贯各种网络协议,是应用程序通过网络协议进行通信的接口。其示意图如下下图所示:

(来自《Java TCP/IP Socket 编程》)

从上图可知,套接字 Socket 在 OSI 七层模型中处于应用层和传输层之间,是一个重要的接口。一般来说,传输层协定有 TCP 协定和 UDP 协定。这两个协定底层都基于 IP 网络层协定。

2 Java Socket 实现
在 Java SDK 中,对于 Socket 原生提供了反对,它分为 ServerSocket 和 Socket,其中 ServerSocket 发动一个服务端的 Socket,其中须要提供一个端口号,如果给定 0,则主动申请可用的端口。当然了,也能够指定具体的端口号(有肯定的范畴,不超过 65535)。不过这里须要留神,传入的端口不能被其余利用占用,否则启动服务失败。上面给出一个简略的 ServerSocket 示例,代码如下:

package com.example.demo.network;
import java.io.IOException;
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 MyServer {
    //<= 65535
    private static final int PORT = 65535;

    public static void main(String[] args) throws Exception {try (ServerSocket listener = new ServerSocket(PORT)) {System.out.println("Server Started");
            // 线程池大小,它依据客户端数来决定,当大于 10 时,则之前的 10 个线程依然能够工作,// 而超过的线程则进入队列中,期待。// 当之前的客户端开释量后,则在队列中的线程依然能够工作。ExecutorService pool = Executors.newFixedThreadPool(10);
            while (true) {
                // 多线程
                pool.execute(new MyServerDemo01(listener.accept()));
                System.out.println(pool);
            }
        }
    }
    //Runnable 接口的实现对象能够被线程 Thread 调用
    private static class MyServerDemo01 implements Runnable {

        private Socket socket;

        MyServerDemo01(Socket socket) {this.socket = socket;}

        @Override
        public void run() {System.out.println("Client [" + socket.getRemoteSocketAddress().toString()+"] Connected");
            try {
                // 输出
                Scanner in = new Scanner(socket.getInputStream());
                // 输入
                PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
                while (in.hasNextLine()) {String msg = in.nextLine();
                    System.out.println("Client [" + socket.getRemoteSocketAddress().toString()+"] :" + msg);
                    out.println(msg.toUpperCase());
                }
            } catch (Exception e) {System.out.println("Error:" + socket+ e.getMessage());
            } finally {
                try {
                    // 敞开 socket
                    socket.close();} catch (IOException e) {e.printStackTrace();
                }
                System.out.println("Closed:" + socket);
            }
        }
    }
}

启动该 Server 端,并开始监听客户端的连贯。当客户端没有连贯时,服务器线程池 pool 并未启动独自的线程。上面给出客户端的 Java Socket 实现,具体的示例代码如下:

package com.example.demo.network;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
public class MyClient {
    //<= 65535
    private static final int PORT = 65535;
    // 服务器地址
    private static final String IP = "127.0.0.1";

    public static void main(String[] args) throws Exception {try (Socket socket = new Socket(IP, PORT)) {System.out.println("Client ["+socket.getRemoteSocketAddress().toString()+"] Started");
            Scanner scanner = new Scanner(System.in);
            Scanner in = new Scanner(socket.getInputStream());
            PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
            while (scanner.hasNextLine()) {out.println(scanner.nextLine());
                System.out.println("Server Response:"+ in.nextLine());
            }
        }catch (Exception ex){System.out.println("Error :"+ ex.getMessage());
        }
    }
}

从代码可知,try (Socket socket = new Socket(IP, PORT)) 是一种蕴含资源开释的 try-with-resource 机制,它会主动进行资源开释,而不须要手动进行开释。Socket 对象要想和服务器通信,必须要明确服务器的 IP 地址和端口,否则不能正确通信,Socket 启动时,也会在主机上占用本人的端口。咱们首先启动 Server 端,而后能够同时启动 10 个以上的 Client 端,比方 13 个,那么超过 Executors.newFixedThreadPool(10)限定的数量 10 后,将进入 queued tasks 队列中进行排队期待。通过打印 pool 对象,能够看出以后的状态,比方 [Running, pool size = 4, active threads = 4, queued tasks = 0, completed tasks = 0] 阐明以后在运行状态,线程池大小为 10,激活的线程为 10,期待的工作线程 queued tasks 为 0。

上面给出 Server 端相干输入示例:

Server Started
java.util.concurrent.ThreadPoolExecutor@256216b3[Running, pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]
Client [/127.0.0.1:64590] Connected
java.util.concurrent.ThreadPoolExecutor@256216b3[Running, pool size = 2, active threads = 2, queued tasks = 0, completed tasks = 0]
Client [/127.0.0.1:64597] Connected
java.util.concurrent.ThreadPoolExecutor@256216b3[Running, pool size = 3, active threads = 3, queued tasks = 0, completed tasks = 0]
Client [/127.0.0.1:64603] Connected
Client [/127.0.0.1:64590] : hello
Client [/127.0.0.1:64590] : hello
Client [/127.0.0.1:64597] : world
Client [/127.0.0.1:64597] : world
Client [/127.0.0.1:64603] : python
Client [/127.0.0.1:64597] : python02
java.util.concurrent.ThreadPoolExecutor@256216b3[Running, pool size = 4, active threads = 4, queued tasks = 0, completed tasks = 0]
Client [/127.0.0.1:57806] Connected
java.util.concurrent.ThreadPoolExecutor@256216b3[Running, pool size = 5, active threads = 5, queued tasks = 0, completed tasks = 0]
Client [/127.0.0.1:57814] Connected
java.util.concurrent.ThreadPoolExecutor@256216b3[Running, pool size = 6, active threads = 6, queued tasks = 0, completed tasks = 0]
Client [/127.0.0.1:57820] Connected
java.util.concurrent.ThreadPoolExecutor@256216b3[Running, pool size = 7, active threads = 7, queued tasks = 0, completed tasks = 0]
Client [/127.0.0.1:57827] Connected
java.util.concurrent.ThreadPoolExecutor@256216b3[Running, pool size = 8, active threads = 8, queued tasks = 0, completed tasks = 0]
Client [/127.0.0.1:57833] Connected
java.util.concurrent.ThreadPoolExecutor@256216b3[Running, pool size = 9, active threads = 9, queued tasks = 0, completed tasks = 0]
Client [/127.0.0.1:57839] Connected
java.util.concurrent.ThreadPoolExecutor@256216b3[Running, pool size = 10, active threads = 10, queued tasks = 0, completed tasks = 0]
Client [/127.0.0.1:57845] Connected
java.util.concurrent.ThreadPoolExecutor@256216b3[Running, pool size = 10, active threads = 10, queued tasks = 1, completed tasks = 0]
java.util.concurrent.ThreadPoolExecutor@256216b3[Running, pool size = 10, active threads = 10, queued tasks = 2, completed tasks = 0]
java.util.concurrent.ThreadPoolExecutor@256216b3[Running, pool size = 10, active threads = 10, queued tasks = 3, completed tasks = 0]
Closed: Socket[addr=/127.0.0.1,port=64590,localport=65535]
Client [/127.0.0.1:57854] Connected
Client [/127.0.0.1:57814] : t2
Client [/127.0.0.1:57814] : tw2

客户端相干输入输出界面如下:

Client [/127.0.0.1:65535] Started
world
Server Response:WORLD
world
Server Response:WORLD
python02
Server Response:PYTHON02

好买网 IT 技术交易网站

正文完
 0