最近学习JAVA网络编程,在服务器端和客户端产生一个Socket 后,

两边各自用getIputStream()和getOutputStream()方法,构造各自的输入输出流。

其中服务器端的Socket ss

BufferedReader is=new BufferedReader(new InputStreamReader(ss.getInputStream()) );

PrintWriter  os=new PrintWriter (new OutputStreamWriter(ss.getOutputStream()) );

os.writer("一个乱七八糟的字符串");

客户端的Socket cs

BufferedReader is=new BufferedReader(new InputStreamReader(cs.getInputStream()) );

PrintWriter  os=new PrintWriter (new OutputStreamWriter(cs.getOutputStream()) );

System.out.println(is.readLine());

按理说,应该是ss的 os对应着cs的 is.  为什么在服务器端写入了,在客户端这边没法读出来呢?

另外,如果服务器端用os.println("字符串");就好使了。

请问这是问什么?

以下整理了开源中国社区的回答:

  • print() 方法等同于 write() 方法

    println() 方法是在 print() 的基础上多调用了一个 newLine() 方法(私有方法)

    而 newLine() 方法会调用 flush()

    所以关键在于 flush()

  • 补充下,我只是把我出问题的关键程序段概括的写出来了,不要说我没刷新服务器Socket的输出流。

    最好有个人能好好解释解释有关IO中的输出流中的writer。以及如何从一个输出流中提取用write()方法写入到该流中的字符。

  • 你用PrintWriter,确实就应该调用println()方法,而不是父类集成过来的write方法。因为PrintWriter本身就是用来执行Print操作的。显然那个write方法是直接继承了父类的方法,可能子类中没有重写或者做了其他操作。

    btw socket通信最好使用DataInputStream和DataOutputStream去封装读写的操作,或者用 ObjectInputStream和ObjectOutputStream,而不要使用你写的BufferedReader和 BufferedWriter。

  • 关键是客户端是is.readLine(),println是会自动在字符后面加上回车换行符的,或者你在服务端os.writer("一个乱七八糟的字符串\r\n");
     
    • 的确是要加上/r /n 有没有比较详细的原因?
  • 查了一下,网上有很多人问这个问题,老外多一下。

    问题主要集中在,为什么客户端调用了write()和flush()后,服务器端依然read不到数据。因为 socket.getOutputStream()取到的实现类是java.net.SocketOutputStream,这个类并没有覆写flush 方法,它的父类java.io.FileOutputStream也没有覆写,于是最终就调到了最顶层java.io.OutputStream的 flush()方法,这就恶心了,这个方法是空的。于是...

    因此,还是使用Reader.readLine()和Writer.println()来处理socket吧,或者直接使用NIO。

    (注意,SocketOutputStream类在JavaDoc中不存在,只在源码中有,他是个受保护的类。)

  • 光说我的了,lz用的是PrintWriter,自己实现了flush,但也是调用内部包装的子对象的,且受autoFlush属性控制,可能跟我的情况不太一样。但可以确定就是flush和\r\n的问题,可以调试一下代码看看。
  • print() 方法等同于 write() 方法

    println() 方法是在 print() 的基础上多调用了一个 newLine() 方法(私有方法)

    而 newLine() 方法会调用 flush()

    所以关键在于 flush()

  • 关键是客户端是is.readLine(),println是会自动在字符后面加上回车换行符的,或者你在服务端os.writer("一个乱七八糟的字符串\r\n");
     这个根据系统而定。我机器貌似就不支持。
    如果一定要用write()的话,就在加一句printWriter.println()即可。因为newLine()方法是私有的,外部无法直接调用
     

JAVA printWriter中write()和println()区别的更多相关文章

  1. Java开发中RMI和webservice区别和应用领域

    Java开发中RMI和webservice区别和应用领域 一.RMI和webservice区别和联系 0. 首先,都是远程调用技术. 1. RMI是在TCP协议上传递可序列化的java对象(使用Str ...

  2. 转:PrintWriter中write与println方法的区别

    原文地址:https://blog.csdn.net/qq_25610165/article/details/57083118 自己遇到的问题是:刚开始学 socket 通讯, 代码运行是好着的,后来 ...

  3. java Scanner中next和nextLine()区别

    next(): 1.一定要读取到有效字符后才可以结束输入. 2.对输入有效字符之前遇到的空白,next() 方法会自动将其去掉. 3.只有输入有效字符后才将其后面输入的空白作为分隔符或者结束符. ne ...

  4. 【java基础 15】java代码中“==”和equals的区别

    导读:昨夜闲来无事,和贾姑娘聊了聊java基础,然后就说到了这个"=="和equals的问题,我俩都是以前了解过,也常用这个,但是,昨天说到的时候,又乱了,什么比较地址值,什么判断 ...

  5. java线程中yield(),sleep(),wait()区别详解

    1.sleep() 使当前线程(即调用该方法的线程)暂停执行一段时间,让其他线程有机会继续执行,但它并不释放对象锁.也就是说如果有synchronized同步快,其他线程仍然不能访问共享数据.注意该方 ...

  6. java集合中List与set的区别

       java集合中List与set的区别.     List可以存储元素为有序性并且元素可以相同.     set存储元素为无序性并且元素不可以相同.     下面贴几段代码感受一下: ArrayL ...

  7. Java线程中yield与join方法的区别

    长期以来,多线程问题颇为受到面试官的青睐.虽然我个人认为我们当中很少有人能真正获得机会开发复杂的多线程应用(在过去的七年中,我得到了一个机会),但是理解多线程对增加你的信心很有用.之前,我讨论了一个w ...

  8. java中ArrayList 、LinkList区别

    转自:http://blog.csdn.net/wuchuanpingstone/article/details/6678653 个人建议:以下这篇文章,是从例子说明的方式,解释ArrayList.L ...

  9. java中equals和==的区别 (转)

    java中equals和==的区别  值类型是存储在内存中的堆栈(以后简称栈),而引用类型的变量在栈中仅仅是存储引用类型变量的地址,而其本身则存储在堆中. ==操作比较的是两个变量的值是否相等,对于引 ...

随机推荐

  1. Nginx+Tomcat动静分离脚本

    #!/bin/bashsetenforce 0systemctl stop firewalldtar -zxvf nginx-1.8.0.tar.gz -C /usr/src/ cd /usr/src ...

  2. UNIX标准

    背景 人们在UNIX编程环境和C 程序设计语言的标准化方面已经做了很多工作.虽然UNIX应用 程序在不同的UNIX操作系统版本之间进行移植相当容易,但是2 0 世 纪 80年代UNIX版本种类的剧增以 ...

  3. [SinGuLaRiTy] 树形存储结构阶段性测试

    [SinGuLaRiTy-1011] Copyright (c) SinGuLaRiTy 2017. All Rights Reserved. G2019级信息奥赛专项训练 题目 程序名 时间 内存 ...

  4. POPTEST老李分享修改dns ip的vbs代码

    POPTEST老李分享修改dns ip的vbs代码   poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.如果对课程感兴趣,请大家咨 ...

  5. 转接口IC GM7150BN/ GM7150BC:CVBS转BT656芯片 低功耗NTSC/PAL 视频解码器

    1 概述    GM7150 是一款9 位视频输入预处理芯片,该芯片采用CMOS 工艺,通过I2C 总线与PC 或DSP 相连构成应用系统.    它内部包含1 个模拟处理通道,能实现CVBS.S-V ...

  6. php运算时默认的类型转换

    php属于弱类型语言,使用数据时无需指定其数据类型.对于学C语言入门的我,刚刚接触时感觉很神奇,但是随之而来的也有烦恼. 总结一下php中默认的类型转换,按照运算符类型,只总结能够自动做类型转换的运算 ...

  7. Struts2基础学习(五)—拦截器

    一.概述 1.初识拦截器      Interceptor 拦截器类似前面学过的过滤器,是可以在action执行前后执行的代码,是我们做Web开发经常用到的技术.比如:权限控制.日志等.我们也可以将多 ...

  8. XML文档结构

    <?xml version="1.0" encoding="UTF-8"?> <books> <bool id="bk1 ...

  9. oralce set

    1         SET TIMING ON 说明:显示SQL语句的运行时间.默认值为OFF. 在SQLPLUS中使用,时间精确到0.01秒.也就是10毫秒. 在PL/SQL DEVELOPER 中 ...

  10. java线程池ThreadPoolExector源码分析

    java线程池ThreadPoolExector源码分析 今天研究了下ThreadPoolExector源码,大致上总结了以下几点跟大家分享下: 一.ThreadPoolExector几个主要变量 先 ...