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

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

}
}

3.2 客户端代码
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();
}
}
}

四、产生问题
      服务器只提示一个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毫秒,结果
   3、接着我又在想,既然不是这个原因,那么会不会是因为封装的字符流问题,于是我将BufferedReader 换成DataInputStreamStream,BufferedWriter 换成DataOutputStream,结果意外的发现竟然能够得到正确结果,但是我始终没法真正的发现发生错误的本质原因,难道以后都不用BufferedReader和BufferedWriter,心里总有一点不快的感觉,但是很无奈,只好放了放。
   4、功能解决了,但是问题的根本原因没有找到,项目时间又紧迫,所以只好放了放,接着学习别的,就在昨天,我漫不经心的看看JDK帮助文档中的BufferedReader这个类以及比较我的代码看了,就看到readLine()方法,上面的提示是
该方法功能,读取一个文本行。通过下列字符之一即可认为某行已终止:换行 ('\n')、回车 ('\r') 或回车后直接跟着换行。 于是我在想如果没有输入换行 ('\n')、回车 ('\r') ,那这个方法就一直阻塞在哪里吗?正好想到我写入输出流的文字没有换行,难道是这个原因,于是改了改调试了一下,果然
五、总结
   在BufferedReader中的readLine方法读入时是读入一行,一定要包括换行符\n在用bufferedwriter的write方法写入的str不包括换行符导致停在了reanline。因此即时flush也是没有用,readLine方法认为你没有读完。一直阻塞在那。
  

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


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论