zoukankan      html  css  js  c++  java
  • IO创建Socket通信中慎用BufferReader中的readLine()

    在编写Socket的Demo的时候,在Server中使用BufferReader获取从客服端发送过来的内容

    package cn.lonecloud.socket;
    
    import cn.lonecloud.thread.factory.TraceThreadPool;
    
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.PrintWriter;
    import java.net.Socket;
    import java.time.Instant;
    import java.time.LocalDateTime;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.SynchronousQueue;
    import java.util.concurrent.ThreadPoolExecutor;
    import java.util.concurrent.TimeUnit;
    
    /**
     * @author lonecloud
     * @version v1.0
     * @date 下午5:11 2018/5/9
     */
    public class SocketServer {
         //创建线程
        static ExecutorService service = new ThreadPoolExecutor(0, 10, 60L, TimeUnit.SECONDS, new SynchronousQueue<>());
       //处理消息类
        static class HandlerMsg implements Runnable {
            //客户端socket
            Socket clientSocket;
    
            public HandlerMsg(Socket clientSocket) {
                this.clientSocket = clientSocket;
            }
    
            @Override
            public void run() {
                BufferedReader reader = null;
                PrintWriter pr = null;
                try {
                   //获取消息
                    reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
                    pr = new PrintWriter(clientSocket.getOutputStream(), true);
                    Instant now = Instant.now();
                    String s = null;
                    while ((s = reader.readLine()) != null) {
                        pr.append(s);
                    }
                    pr.close();
                    reader.close();
                    clientSocket.close();
                    System.out.println("spend "+(Instant.now().getNano()-now.getNano()));
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    

      client

    package cn.lonecloud.socket;
    
    import java.io.*;
    import java.net.InetSocketAddress;
    import java.net.Socket;
    import java.util.Scanner;
    
    /**
     * @author lonecloud
     * @version v1.0
     * @date 下午5:24 2018/5/9
     */
    public class SocketClient {
    
        public static void main(String[] args) throws IOException {
            Socket socket=new Socket();
         //链接 socket.connect(new InetSocketAddress("localhost",8000)); PrintWriter printWriter = new PrintWriter(socket.getOutputStream(),true); //获取输入
         Scanner scanner=new Scanner(System.in); String s = scanner.nextLine(); //必须使用println不然会一直卡在这里
         printWriter.println(s); printWriter.flush();
         //读取数据 InputStream inputStream = socket.getInputStream(); BufferedReader reader=new BufferedReader(new InputStreamReader(inputStream)); //打印
         System.out.println("from server"+reader.readLine()); System.out.flush(); printWriter.close(); reader.close(); socket.close(); } }

      Main

    package cn.lonecloud.socket;
    
    import java.io.IOException;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    /**
     * @author lonecloud
     * @version v1.0
     * @date 下午5:21 2018/5/9
     */
    public class ServerMain {
        public static void main(String[] args) throws IOException {
            ServerSocket serverSocket = null;
            Socket clientSocket = null;
            serverSocket = new ServerSocket(8000);
            while (true) {
                clientSocket = serverSocket.accept();
                System.out.println(clientSocket.getRemoteSocketAddress() + "connect");
                SocketServer.service.execute(new SocketServer.HandlerMsg(clientSocket));
            }
        }
    }
    

      出现如下问题,如果Socket中如果对采用如下代码

    while ((s = reader.readLine()) != null) {
                        pr.append(s);
                    }
    

      如果其在客户端不采用println打印换行符,将导致客户端与服务器端一直处于工作状态,因为其一直都未接收到" "

  • 相关阅读:
    checkedListBox 的用发
    C# 控件命名规范
    控件数据及相应的事件处理
    MDI 窗口的创建
    摄像头中运动物体识别
    1
    静态检测大风车初版
    不会难道我还不能附上链接吗
    计算机操作素材
    数字识别
  • 原文地址:https://www.cnblogs.com/lonecloud/p/9015866.html
Copyright © 2011-2022 走看看