• 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打印换行符,将导致客户端与服务器端一直处于工作状态,因为其一直都未接收到" "

  • 相关阅读:
    .NET 分布式架构开发实战之一
    frame中隐藏横向滚动条
    实时检测网络状态及是否可以连接Internet
    jquery表格插件推荐
    FireFox窗体frameset,iframe间的js调用方法
    用C#实现实现简单的 Ping 的功能,用于测试网络是否已经联通
    一个阴历阳历互相转化的类
    CSS技巧 — 不使用图片实现圆角、阴影、渐变等功能
    Windows下命令行下启动ORACLE服务
    使用C#进行点对点通讯和文件传输(通讯基类部分)
  • 原文地址:https://www.cnblogs.com/lonecloud/p/9015866.html
Copyright © 2020-2023  润新知