当前位置: 首页 > news >正文

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

相关文章:

  • lambda表达式的简单入门
  • 提交表单且不刷新页面
  • selenium+python 优化测试报告
  • Kylin性能调优记——业务技术两手抓
  • 编译时
  • 详解PHP魔术函数、魔术常量、预定义常量
  • 聊一聊session和cookie
  • 通过Struts2Web应用框架深入理解MVC
  • 酒店管理系统
  • 前端人工智能?TensorFlow.js 学会游戏通关
  • 从 源码 谈谈 redux compose
  • 【译】理解JavaScript:new 关键字
  • 开发者论坛一周精粹(第四十三期) 物联网全栈教程 ECSphp版本降级
  • Waymo宣布今年在凤凰城推出自动驾驶汽车打车服务,此前已获得商业执照
  • 数学随记—公式定理
  • angular组件开发
  • C++类中的特殊成员函数
  • Date型的使用
  • ES学习笔记(12)--Symbol
  • express如何解决request entity too large问题
  • gops —— Go 程序诊断分析工具
  • Gradle 5.0 正式版发布
  • Iterator 和 for...of 循环
  • Java 11 发布计划来了,已确定 3个 新特性!!
  • JAVA并发编程--1.基础概念
  • js作用域和this的理解
  • MyEclipse 8.0 GA 搭建 Struts2 + Spring2 + Hibernate3 (测试)
  • node和express搭建代理服务器(源码)
  • Sass 快速入门教程
  • SQLServer插入数据
  • Theano - 导数
  • 闭包--闭包作用之保存(一)
  • 分享自己折腾多时的一套 vue 组件 --we-vue
  • 类orAPI - 收藏集 - 掘金
  • 设计模式(12)迭代器模式(讲解+应用)
  • 使用权重正则化较少模型过拟合
  • 用Visual Studio开发以太坊智能合约
  • Semaphore
  • ​LeetCode解法汇总2583. 二叉树中的第 K 大层和
  • #经典论文 异质山坡的物理模型 2 有效导水率
  • (20050108)又读《平凡的世界》
  • (9)目标检测_SSD的原理
  • (LeetCode 49)Anagrams
  • (二)换源+apt-get基础配置+搜狗拼音
  • (附源码)springboot 房产中介系统 毕业设计 312341
  • (附源码)springboot学生选课系统 毕业设计 612555
  • .net 后台导出excel ,word
  • .NET/C# 使窗口永不激活(No Activate 永不获得焦点)
  • .net网站发布-允许更新此预编译站点
  • @for /l %i in (1,1,10) do md %i 批处理自动建立目录
  • [.net] 如何在mail的加入正文显示图片
  • [].shift.call( arguments ) 和 [].slice.call( arguments )
  • [2018/11/18] Java数据结构(2) 简单排序 冒泡排序 选择排序 插入排序
  • [Android]使用Android打包Unity工程
  • [Angular 基础] - 自定义指令,深入学习 directive