Socket getInputStream().read() 返回-1

luojihaidao 2010-09-07 09:14:25
如题:

首先TCP通握手建立了连接。


byte[] buf = new byte[1024];
InputStream in = socket.getInputStream();//socket 是已经建立好了的一个Socket连接
int c = in.read(buf);



在运行中 有时会出现c为-1。

查看API:

如果 b 为 null,将抛出 NullPointerException。如果 b 的长度为 0,则无字节可读且返回 0;否则,要尝试读取至少一个字节。如果因为流位于文件末尾而没有可用的字节,则返回值 -1;否则,至少可以读取一个字节并将其存储在 b 中。

上面说明:因为流位于文件末尾而没有可用的字节。


不明白的地方: 在网络Socket使用上会出现流位于文件末尾? in.read(buf)方法是阻塞的,如果没有数据过来的话。应该会一直等待。

高手帮忙分析下 在什么情况下出现返回-1。

...全文
1732 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
kokobox 2010-09-07
  • 打赏
  • 举报
回复
你的服务器端的输出流没有关闭

OutputStream out = skt.getOutputStream();

out没关闭!

操作结束以后要关闭掉,包括skt

xianaofei 2010-09-07
  • 打赏
  • 举报
回复
用while循环判断一下啊
luojihaidao 2010-09-07
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 soli11722984 的回复:]
换行
回车
[/Quote]

简单测试了一下。 不会出现返回-1情况。

测试代码:

client:

public class TcpClient {

public static void main(String[] a) {
try {
Socket skt = new Socket(InetAddress.getLocalHost(), 10001);
InputStream in = skt.getInputStream();
OutputStream out = skt.getOutputStream();
byte[] b = new byte[100];
int c = in.read(b);

for (int i = 0; i < c; i++) {
System.out.println(b[i]);
}

if (c > 0) {
byte[] buf = {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, 1, 0, 16, 0, 2, 0, 'a', 'b'};
out.write(buf);
out.flush();
}
skt.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}




server:

public class TcpServer {

public static void main(String[] a) {
try {
ServerSocket sskt = new ServerSocket(10001);
while (true) {
Socket skt = sskt.accept();
OutputStream out = skt.getOutputStream();
byte[] buf = new byte[2];
buf[0] = 0x0D;
buf[1] = 0x0A;
out.write(buf);
}

} catch (IOException e) {

e.printStackTrace();
}

}
}
luojihaidao 2010-09-07
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 kokobox 的回复:]
你把每次服务器端输出打印出来,我估计程序返回-1就是服务器端没有输出相应字节造成的。
[/Quote]

没有输出相应字节 客户端应该阻塞的。
kokobox 2010-09-07
  • 打赏
  • 举报
回复
你把每次服务器端输出打印出来,我估计程序返回-1就是服务器端没有输出相应字节造成的。

szaiguoguo 2010-09-07
  • 打赏
  • 举报
回复
关注
一般都是用>0判断有没读入,还真没想过会有<0这种情况出现
luojihaidao 2010-09-07
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 soli11722984 的回复:]
换行
回车
[/Quote]

但是没有传过换行 回车的呀
luojihaidao 2010-09-07
  • 打赏
  • 举报
回复
socket.getInputStream()的实现类为:java.net.SocketInputStream
soli11722984 2010-09-07
  • 打赏
  • 举报
回复
换行
回车
closewbq 2010-09-07
  • 打赏
  • 举报
回复
luojihaidao 2010-09-07
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 kokobox 的回复:]
你的服务器端的输出流没有关闭

OutputStream out = skt.getOutputStream();

out没关闭!

操作结束以后要关闭掉,包括skt
[/Quote]

不是out没关闭! 正是因为out关闭了才会出现返回-1情况。

先说说我的程序大概:

1.握手。(建立Socket);

2.在客户端使用统一的一个线程接收这一Socket的数据。服务器端写数据到客户端。

代码:OutputStream out = skt.getOutputStream(); out.write();

如果这里out.close(); (此时Socket没有关闭,只时关闭了流),下次out.write()后,在接收端in.read();就会返回-1;

测试代码如下:

server:


public class TcpServer {

public static void main(String[] a) {
try {
ServerSocket sskt = new ServerSocket(10001);
Socket skt = sskt.accept();
while (true) {

OutputStream out = skt.getOutputStream();
byte[] buf = new byte[2];
buf[0] = 0x0D;
buf[1] = 0x0A;
out.write(buf);
out.flush();
out.close(); // 如果这里关闭了。 就会返回-1;
Thread.sleep(2000);
byte[] buf1 = new byte[2];
buf1[0] = 0x0D;
buf1[1] = 0x0A;
out = skt.getOutputStream();
out.write(buf1);
out.flush();
}

} catch (IOException e) {

e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}

}
}


client:

public class TcpClient {

public static void main(String[] a) {
try {
Socket skt = new Socket(InetAddress.getLocalHost(), 10001);
InputStream in = skt.getInputStream();
OutputStream out = skt.getOutputStream();
while (true) {
byte[] b = new byte[100];
int c = in.read(b);
System.out.println(c);
}

} catch (IOException e) {
e.printStackTrace();
}
}
}


67,513

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧