基于TCP的客户端与服务器端通阻塞问题以及个人纠错心得

一、背景
在前段时间写项目时,需要用到SOCKET编程,于是看看帮助文档,简单的写了一个小例子,他娘的,尽然发现一个无法解释的问题,于是不断的调试, :cry: 还好终于知道出错的原因在哪里,觉得在项目中可能遇见,特别是初学者故此将心得写下。
二、实现功能
超级简单的例子,就是客户端连接到服务器端后,发送hello server给服务器端,而服务器端首先拿到客户端传过来的信息,打印到控制台上,接着再向客户端发送hello client的信息。***补充说明--该例子只是本人在入门学习socket编程乱写的,所以功能简单。***
三、项目代码
3.1 服务器端代码
[size=medium][color=red]package com.congine.socket.test;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class TcpServerStu2 {

public static void main(String[] args) {
try {
ServerSocket ss = new ServerSocket(8888);
Socket s = null;
while(true) {
s = ss.accept();
System.out.println("a client connection!");
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
System.out.println("client say:"+br.readLine());
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
bw.write("hello client!");
bw.flush();
bw.close();
br.close();
s.close();
}
} catch (IOException e) {
e.printStackTrace();
}

}
}[/color][/size]
3.2 客户端代码
[size=medium][color=red]package com.congine.socket.client.test;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;


public class TcpClient2 {

public static void main(String[] args) {
try {
Socket s = new Socket("127.0.0.1",8888);
BufferedWriter dos = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
dos.write("hello server!");
dos.flush();
System.out.println("hello world!");
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
System.out.println("server say:"+br.readLine());
dos.close();
br.close();
s.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}[/color][/size]
四、产生问题
服务器只提示一个a client connection,而客户端就是打印hello world,接着服务器和客户端就阻塞到哪里,傻傻的等待。
五、问题的假想
1、 产生以上问题以后,第一时间我就利用IDE的调试来查看执行的过程,于是我在server端设置一个断点,接着在client端设置一个断点。然后,我开始用debug方式启动服务器端,跟预想的一样,服务器端在ss.accept()阻塞住,接着我再启动client端,发现client可以执行到末尾br.readLine()处阻塞,程序就没法执行了,跟预想的不一样,预想中根据程序运行的结果,在调试Client端应该有一个时间点切换到server端打印 a client connection,可是结果却没有。那么这里肯定存在一个问题,IDE的debug运行机制跟RUN运行机制不一样,哈哈,各位有兴趣可以去研究。
2、接着我就在考虑,既然两端都没有接收到双方的信息,并且发生阻塞(相当于死循环),那是不是client端发送的数据和server端发送的数据在同一个IO通道中阻塞住了,因此接收不到,(哈哈,现在想想发现当时的想法很幼稚),于是我就按着这种思路走,在服务器的打印了a client connection后,让服务器线程休眠1000毫秒,结果 :shock:
3、接着我又在想,既然不是这个原因,那么会不会是因为封装的字符流问题,于是我将BufferedReader 换成DataInputStreamStream,BufferedWriter 换成DataOutputStream,结果意外的发现竟然能够得到正确结果,但是我始终没法真正的发现发生错误的本质原因,难道以后都不用BufferedReader和BufferedWriter,心里总有一点不快的感觉,但是很无奈,只好放了放。
4、功能解决了,但是问题的根本原因没有找到,项目时间又紧迫,所以只好放了放,接着学习别的,就在昨天,我漫不经心的看看JDK帮助文档中的BufferedReader这个类以及比较我的代码看了,就看到readLine()方法,上面的提示是
该方法功能,读取一个文本行。通过下列字符之一即可认为某行已终止:换行 ('\n')、回车 ('\r') 或回车后直接跟着换行。 于是我在想如果没有输入换行 ('\n')、回车 ('\r') ,那这个方法就一直阻塞在哪里吗?正好想到我写入输出流的文字没有换行,难道是这个原因,于是改了改调试了一下,果然 :wink:
五、总结
在BufferedReader中的readLine方法读入时是读入一行,一定要包括换行符\n在用bufferedwriter的write方法写入的str不包括换行符导致停在了reanline。因此即时flush也是没有用,readLine方法认为你没有读完。一直阻塞在那。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值