不写java代码好久,临时写个socket通讯竟然失败,郁闷之下仔细研究了下。

客户端使用BufferedReader来读取数据,在while中调用BufferedReader.readLine()函数,结果程序运行起来之后一直死等,就是不输出想要的结果。

google发现 readLine()方式是读行的,所以只有遇到换行符或者流结束的时候才会得到结果,在window系统下使用"\r\n"代替换行符,验证ok。

即在我们一般的服务端输出信息

printWriter.write("news");

//输入换行符并发送到客户端

printWriter.write("\r\n");

printWriter.flush();

下面附上几个简单源码:小弟这里是用来解决flex调用socket垮与文件许可的,所以下面内容也是以此为例,服务需支持多次调用,客户端接收到跨域文件后则关闭

首先是最直接的,不使用BufferedReader(),个人感觉这个更简单清晰些

服务端,客户端都使用DataInputStream; DataOutputStream();

服务代码:

public class Server {
public static void main(String args[]){
try {
DataInputStream din;
DataOutputStream dout; ServerSocket server = new ServerSocket(4444); while(true){
Socket client = server.accept();
din = new DataInputStream(client.getInputStream());
dout = new DataOutputStream(client.getOutputStream()); String s;
if((s = din.readUTF()) != null){
System.out.println(s);
} if(s.equals("<policy-file-request/>")){
String msg = "<?xml version=\"1.0\"?>" + "<cross-domain-policy>"
+ "<site-control permitted-cross-domain-policies=\"all\"/>"
+ "<allow-access-from domain=\"*\" to-ports=\"*\" />"
+ "</cross-domain-policy>";
dout.writeUTF(msg);
}
din.close();
dout.close();
client.close();
} } catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} }
}

客户端:

public class Client {

	public static void main(String args[]){

		DataInputStream din;
DataOutputStream dout;
try {
Socket client = new Socket("127.0.0.1", 2000); din = new DataInputStream(client.getInputStream());
dout = new DataOutputStream(client.getOutputStream());
dout.writeUTF("<policy-file-request/>"); String s = null;
if((s=din.readUTF()) != null){
System.out.println(s);
}
din.close();
dout.close();
client.close(); } catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} }
}

更换客户端接收为BufferedReader,使用readLine()方法。如果继续使用上面的服务,那么依然是没有错的....因为上面的服务段在信息输出之后理科调用了dout.colse方法。正如我们开始说的,当流结束的时候readLine()方法也能读取到结果。  如果是想实现一个客户端和服务端保持连接一直交互通讯的功能,那么请在上面的信息输入完成后添加如下代码

dout.writeUTF(msg);//补充
//因为在客户端使用bufferedReader.readLine()在读取,这里必须输入换行符,
//并且调用fluesh(),方法。否则客户端将陷入死等状态
dout.writeUTF("\r\n");
dout.flush();

此时客户端代码如下:

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException; public class Client { public static void main(String args[]){ DataOutputStream dout;
BufferedReader br;
PrintWriter out;
try {
Socket client = new Socket("127.0.0.1", 4444); br = new BufferedReader(new InputStreamReader(client.getInputStream(),"UTF-8"));
dout = new DataOutputStream(client.getOutputStream());
dout.writeUTF("<policy-file-request/>"); String s = null;
while(true){
s = br.readLine();
if(s != null){
System.out.println(s);
break;
}
} br.close();
dout.close();
client.close(); } catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} }
}

最后,总结两点:

一、readLine()方法,需要明确换行符或者结束符,信息需要flush()才能接受到,增加了两端的信息输入(多输入换行符,并且这个符号不同系统是不一样的)

二,任何流进行写入完成后请调用flush()方法推送下。  以确保正确性

当然bufferedReader在操作字符的时候有很多更直观的接口以供调用,使用过程中需仔细注意

java编写socket使用bufferedReader.readLine()问题研究的更多相关文章

  1. Socket中BufferedReader.readLine()的阻塞特性导致的数据无法多次发送的问题

    https://blog.csdn.net/shenpibaipao/article/details/70236657

  2. Flex通信-与Java实现Socket通信实例

    Flex通信-与Java实现Socket通信实例  转自:http://blessht.iteye.com/blog/1136888 博客分类: Flex 环境准备 [服务器端] JDK1.6,“ja ...

  3. Java:bufferedReader.readLine()读取文件换行问题

    代码实现读取到的内容正常换行,并将内容复制到系统剪贴板当中去. public static void ReadAlart() { try { String encoding="utf-8&q ...

  4. 【Android编程】Java利用Socket类编写Metasploit安卓载荷辅助模块

    /作者:Kali_MG1937 CSDN博客:ALDYS4 QQ:3496925334/ 注意!此文章被作者标记到 黑历史 专栏中,这意味着本篇文章可能存在 质量低下,流水账文,笔法低质 的问题 为了 ...

  5. 简单通过java的socket&serversocket以及多线程技术实现多客户端的数据的传输,并将数据写入hbase中

    业务需求说明,由于公司数据中心处于刚开始部署的阶段,这需要涉及其它部分将数据全部汇总到数据中心,这实现的方式是同上传json文件,通过采用socket&serversocket实现传输. 其中 ...

  6. java编写service详细笔记 - centos7.2实战笔记(windows类似就不在重复了)

    java编写service详细笔记 - centos7.2实战笔记(windows类似就不在重复了)  目标效果(命令行启动服务): service xxxxd start #启动服务  servic ...

  7. loadrunner 编写socket脚本实例(附服务端实现)

    一.socket背景知识 这个咱就不废话了,网上一搜一大堆 二.本实例实现的功能 服务端接收客户端发送的字符串,并返回"5678succ"共8个字符 三.服务端实现(java代码) ...

  8. java基于socket公共聊天室的实现

    项目:一个公共聊天室功能的实现,实现了登录聊天,保存聊天记录等功能. 一.实现代码 1.客户端 ChatClient.java import java.io.BufferedReader; impor ...

  9. JAVA之Socket编程

    网上对Socket的诠释很多,也很全,在这里我就不多说了,总之,现在的网络处处都在使用Socket.本帖是一个Socket的例子,用来模拟一个简单的登录系统,只有核心代码,访问数据库.输入神马的统统没 ...

随机推荐

  1. 计蒜客 28319.Interesting Integers-类似斐波那契数列-递推思维题 (Benelux Algorithm Programming Contest 2014 Final ACM-ICPC Asia Training League 暑假第一阶段第二场 I)

    I. Interesting Integers 传送门 应该是叫思维题吧,反正敲一下脑壳才知道自己哪里写错了.要敢于暴力. 这个题的题意就是给你一个数,让你逆推出递推的最开始的两个数(假设一开始的两个 ...

  2. MyBatis笔记:invalid bound statement (not found)

    maven项目在本地运行的时候没有问题,一旦把war包部署到测试机上就不能运行.查看了一下tomcat日志发现抛出这样的错误:invalid bound statement (not found),后 ...

  3. Cookie和Session在Node.JS中的实践(三)

    Cookie和Session在Node.JS中的实践(三) 前面作者写的COOKIE篇.SESSION篇,算是已经比较详细的说明了两者间的区别.机制.联系了.阅读时间可能稍长,因为作者本身作图也做了不 ...

  4. Go -- 卸载 Go

    直接删除usr下的go文件夹即可 命令行: cd / 1 然后: open usr 1 删除go文件夹

  5. 2. LVS/DR 配置

    平台:RedHat Enterprise Linux centos6.3       ipvsadm             ipvs 1.DR模型 DR模型:直接路由模型,每个Real Server ...

  6. Makefile之文件搜索

    Makefile之文件搜索 1.Makefile 文件中的"VPATH"变量 如果没有指明这个变量,make只会在当前目录下查找依赖文件和目标文件: 如果定义了这个变量,make会 ...

  7. osgconv使用指南(转)

    osgconv是一种用来读取3D数据库以及对它们实施一些简单的操作的实用应用程序,同时也被称作 一种专用3D数据库工具. 用osgconv把其他格式的文件转换为OSG所支持的格式 osgconv是一种 ...

  8. 让Mac支持lrzsz

    http://blog.csdn.net/citywolf4/article/details/49071679 https://github.com/mmastrac/iterm2-zmodem

  9. oracle deadlock

    Basic operation su - oracle sqlplus / as sysdba show parameter background show parameter user_dump_d ...

  10. CentOS7下挂载硬盘笔记

    CentOS7下挂载硬盘笔记 准备工作 机器:DELL R730 系统:CentOS 7.4.1708 (Core) x86_64 新增硬盘:三星960PRO 关闭服务器加上新硬盘,然后重启 查看硬盘 ...