YAN_HUAXIANGMO 2016-11-26 10:18 采纳率: 100%
浏览 1869
已采纳

关于建立一个TCP服务端出现阻塞问题


这里是tcp客户端的代码


import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;

public class Socket_client {

public static void main(String[] args) throws UnknownHostException, IOException {
    //first,创建一个socket对象
    Socket s = new Socket("192.168.1.107",20000);

    //second,获取Socket中的输出流
    OutputStream out = s.getOutputStream();

    //third,发送信息
    out.write("嘿嘿嘿".getBytes());


    //添加读取服务器返回信息功能
    //使用socket流读取服务器返回数据
    InputStream in = s.getInputStream();
    byte[] b = new byte[1024];
    int len = in.read(b);
    String str = new String(b,0,len);
    System.out.println(str);

    //关闭资源
    s.close();

}

}


这里是tcp服务端的代码


import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class Server_Socket {
public static void main(String[] agrs) throws IOException{
//先建立一个服务Socket
ServerSocket ss = new ServerSocket(20000);

    //获取客户Socket对象
    Socket s = ss.accept();

    //使用客户的Socket对象将信息打印出来
    InputStream in = s.getInputStream();
    byte[] b = new byte[1024];
    int len;
    while((len = in.read(b))!=-1){    //问题就出在这里,用循环读取,读取-1时,出现阻塞,后面代码无法运行
        String str = new String(b,0,len);
        System.out.println(str);
    }

    //使用客户的Socket对象将成功接受信息的信息反馈给客户端
    OutputStream out = s.getOutputStream();
    out.write("成功接受到信息".getBytes());

    //关闭资源
    s.close();
    ss.close();
}

}
先执行了服务端,然后再执行客户端,服务端收到客户端发来的string后阻塞了,客户端也阻塞了,无法接受服务端回复的string
如果我把服务端循坏代码改成如下:

//使用客户的Socket对象将信息打印出来
InputStream in = s.getInputStream();
byte[] b = new byte[1024];
int len = in.read(b);
String str = new String(b,0,len);
System.out.println(str);
--------------------------------------------------
程序能正常运行,为何,求解?

  • 写回答

3条回答

  • YAN_HUAXIANGMO 2016-12-09 13:42
    关注

    这个问题本人已经解决了,一直没时间,现在写一下。为什么 while((len=in.read(b))!=-1) 会阻塞呢?这是因为read()在读的时候没有读到结束符,
    也就是说从socket的输入流中没有获取到结束标记,所以一直在等待着客户端继续发送字节,然而客户端已经发送完毕,进行到 “使用socket流读取服务器返回数据”
    这一步,这时,客户端这边的read()开始等待服务端返回的字节,因此,两边就陷入互相等待的状况!!!
    解决办法:在客户端
    //third,发送信息
    out.write("嘿嘿嘿".getBytes());
    //在这一步后面,再加一句作用是加入socket流的结束标志,但并不是关闭流资源,告诉服务端,数据发送完毕,让服务器停止读取
    s.shutdownOutput();

    PS:其实shutdownOutput()这个方法相当于服务端的while((len=in.read())!=null){..........省略; 加入 if(in.read()=="end"){break}},当接受到结束标记“end”的时候就
    跳出循环了,或者理解为传入了一个null,就跳出循环。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥20 sub地址DHCP问题
  • ¥15 delta降尺度计算的一些细节,有偿
  • ¥15 Arduino红外遥控代码有问题
  • ¥15 数值计算离散正交多项式
  • ¥30 数值计算均差系数编程
  • ¥15 redis-full-check比较 两个集群的数据出错
  • ¥15 Matlab编程问题
  • ¥15 训练的多模态特征融合模型准确度很低怎么办
  • ¥15 kylin启动报错log4j类冲突
  • ¥15 超声波模块测距控制点灯,灯的闪烁很不稳定,经过调试发现测的距离偏大