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

时间:2022-08-26 18:57:12
如题:

 首先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。

12 个解决方案

#1


该回复于2010-09-07 09:42:49被版主删除

#2


换行
回车

#3


socket.getInputStream()的实现类为:java.net.SocketInputStream

#4


引用 2 楼 soli11722984 的回复:
换行
回车


但是没有传过换行 回车的呀

#5


关注
一般都是用>0判断有没读入,还真没想过会有<0这种情况出现

#6


你把每次服务器端输出打印出来,我估计程序返回-1就是服务器端没有输出相应字节造成的。

#7


引用 6 楼 kokobox 的回复:
你把每次服务器端输出打印出来,我估计程序返回-1就是服务器端没有输出相应字节造成的。


没有输出相应字节  客户端应该阻塞的。   

#8


引用 2 楼 soli11722984 的回复:
换行
回车


简单测试了一下。 不会出现返回-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();
        }

    }
}

#9


用while循环判断一下啊

#10


你的服务器端的输出流没有关闭

OutputStream out = skt.getOutputStream();

out没关闭!

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

#11


引用 10 楼 kokobox 的回复:
你的服务器端的输出流没有关闭

OutputStream out = skt.getOutputStream();

out没关闭!

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


不是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();
        }
    }
}


#1


该回复于2010-09-07 09:42:49被版主删除

#2


换行
回车

#3


socket.getInputStream()的实现类为:java.net.SocketInputStream

#4


引用 2 楼 soli11722984 的回复:
换行
回车


但是没有传过换行 回车的呀

#5


关注
一般都是用>0判断有没读入,还真没想过会有<0这种情况出现

#6


你把每次服务器端输出打印出来,我估计程序返回-1就是服务器端没有输出相应字节造成的。

#7


引用 6 楼 kokobox 的回复:
你把每次服务器端输出打印出来,我估计程序返回-1就是服务器端没有输出相应字节造成的。


没有输出相应字节  客户端应该阻塞的。   

#8


引用 2 楼 soli11722984 的回复:
换行
回车


简单测试了一下。 不会出现返回-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();
        }

    }
}

#9


用while循环判断一下啊

#10


你的服务器端的输出流没有关闭

OutputStream out = skt.getOutputStream();

out没关闭!

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

#11


引用 10 楼 kokobox 的回复:
你的服务器端的输出流没有关闭

OutputStream out = skt.getOutputStream();

out没关闭!

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


不是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();
        }
    }
}


#12