TCP的Socket编程

服务端

public class TCPServer {
    public static final int SERVER_PORT = 9888;

    public static void main(String[] args) throws IOException{

        // 创建TCP的服务端
        try(ServerSocket serverSocket = new ServerSocket(SERVER_PORT)) {

            while(true){
                // 建立连接
                // 该方法时阻塞的,如果未连接,则会等待有人连接
                Socket socket = serverSocket.accept();

                SocketAddress socketAddress = socket.getRemoteSocketAddress(); // 对方的地址
            int port = socket.getPort();  // 对方的端口


            // 输入流
            InputStream inputStream = socket.getInputStream();
            // 输出流
            OutputStream outputStream = socket.getOutputStream();

            // 读取输入流
            Scanner scanner = new Scanner(inputStream,"UTF-8");
            // 写入
            PrintWriter writer = new PrintWriter(
                    new OutputStreamWriter(outputStream,"UTF-8")

            );

            String request = scanner.nextLine();  // 也是阻塞的
            String response = echoService(request);

            writer.printf("%s\r\n",response);

            writer.flush();
            System.out.println("end");
            socket.close();


            }
        } catch (IOException exception) {
            exception.printStackTrace();
        }
    }
}

客户端

public class TCPClient {

    private static final String SERVER_HOST = "127.0.0.1";
    private static final int SERVER_PORT = TCPServer.SERVER_PORT;

    public static void main(String[] args) throws IOException {

        Scanner scanner = new Scanner(System.in);
        try(Socket socket = new Socket(SERVER_HOST,SERVER_PORT)){

            // 本地地址
            SocketAddress socketAddress = socket.getLocalSocketAddress();
            // 本地端口
            int localPort = socket.getLocalPort();

            // 服务器地址
            SocketAddress socketAddress1 = socket.getRemoteSocketAddress();
            // 都武器端口
            int port = socket.getPort();

            System.out.print("请输入请求: ");
            String request = scanner.nextLine();

            InputStream inputStream = socket.getInputStream();
            OutputStream outputStream = socket.getOutputStream();

            Scanner scan = new Scanner(inputStream,"UTF-8");
            PrintWriter writer = new PrintWriter(
                    new OutputStreamWriter(outputStream,"UTF-8")
            );

            writer.printf("%S\r\n",request);
            writer.flush();

            String response = scan.nextLine();
            System.out.println(response);



        }
    }
}

注意:①这是一个“短连接”客户端,就像打电话一样,有啥事打电话,如果有另外的事再打一个电话,“长连接”只需加一个while循环.
② 当一个同时运行两个客户端,第一个客户端不不发送请求,第二个客户端发送请求,第二个客户端会出现收不到来自服务端的响应,这是因为服务端里面的scanner,nextLine();也是一个阻塞,由于第一个客户端没有发送请求,服务端会一直等待第一个客户端发送请求,所以不会去处理第二个客户端的请求
分析:这是因为单线程的原因,所以,对服务端改造为多线程,利用线程池

将处理的事务拿出来作为单独的一个子线程,这里没有使用加锁关键字synchronized

子线程

public class TCPServerTask implements Runnable{

    private final Socket socket;
    public TCPServerTask(Socket socket){
        this.socket = socket;
    }
    @Override
    public void run() {
        try{ SocketAddress socketAddress = socket.getRemoteSocketAddress(); // 对方的地址
            int port = socket.getPort();  // 对方的端口


            // 输入流
            InputStream inputStream = socket.getInputStream();
            // 输出流
            OutputStream outputStream = socket.getOutputStream();

            // 读取输入流
            Scanner scanner = new Scanner(inputStream,"UTF-8");
            // 写入
            PrintWriter writer = new PrintWriter(
                    new OutputStreamWriter(outputStream,"UTF-8")

            );

            String request = scanner.nextLine();  // 也是阻塞的
            String response = echoService(request);

            writer.printf("%s\r\n",response);

            writer.flush();
            System.out.println("end");
            socket.close();
        } catch (IOException e){
            e.printStackTrace();
        }

    }

    private String echoService(String request) {
        return request;
    }
}

主线程

public static void main(String[] args) throws IOException{

        ExecutorService threadPool = Executors.newFixedThreadPool(8);

        // 创建TCP的服务端
        try(ServerSocket serverSocket = new ServerSocket(SERVER_PORT)) {

            while(true){
                // 建立连接
                // 该方法时阻塞的,如果未连接,则会等待有人连接
                Socket socket = serverSocket.accept();

                Runnable task = new TCPServerTask(socket);
                threadPool.execute(task);


            }
        } catch (IOException exception) {
            exception.printStackTrace();
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值