不写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. Linux下多进程服务端客户端模型二(粘包问题与一种解决方法)

    一.Linux发送网络消息的过程 (1) 应用程序调用write()将消息发送到内核中 ( 2)内核中的缓存达到了固定长度数据后,一般是SO_SNDBUF,将发送到TCP协议层 (3)IP层从TCP层 ...

  2. 【bzoj3687】【简单题】bitset

    [pixiv] https://www.pixiv.net/member_illust.php?mode=medium&illust_id=64333782 这次的图是自己画的,方便的话点个赞 ...

  3. Xcode 5 单元测试(二)OCMock和GHUnit

    在Xcode 5 单元测试(一)使用XCTest进行单元测试中说了如何在Xcode 5中使用XCTest进行简单的单元测试,本文就来探讨下mock测试和更高级的工具GHUnit. Mock 首先科普下 ...

  4. 【Linux】linux下查看目录所在分区

    命令如下: df -h 目录名 具体使用例子如下:查看/home/sxd/文档处于哪个分区 ------------------------------------------------------ ...

  5. ASP.NET 5基础之中间件

    来源https://docs.asp.net/en/latest/fundamentals/middleware.html 一些可以整合进http请求管道的小的应用组件称做中间件.ASP.NET 5集 ...

  6. leetcode题解:Construct Binary Tree from Inorder and Postorder Traversal(根据中序和后序遍历构造二叉树)

    题目: Given inorder and postorder traversal of a tree, construct the binary tree. Note:You may assume ...

  7. 利用fpm定制rpm包

    环境说明 系统版本    CentOS 6.9 x86_64 软件版本    fpm-1.4.0 1.安装ruby环境 fpm利用ruby编程语言开发,先安装ruby的环境 [root@m01 ~]# ...

  8. 转:android实时语音问题分析

    转:http://ticktick.blog.51cto.com/823160/1746136 PigeonCall:一款Android VoIP网络电话App架构分析 2016-02-29 20:1 ...

  9. 命令行设置IE代理

    IE代理可以在注册表中设置,所以用DOS修改注册表,可以达到目的.方法一:注册表文件:REGEDIT4[HKEY_CURRENT_USER\Software\Microsoft\Windows\Cur ...

  10. spring 配置多数据源 (可行)

    可以看到AbstractRoutingDataSource获取数据源之前会先调用determineCurrentLookupKey方法查找当前的lookupKey,这个lookupKey就是数据源标识 ...