Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 从InputStreamReader读取字节进入无限循环_Java_Sockets_Inputstream_Outputstream - Fatal编程技术网

Java 从InputStreamReader读取字节进入无限循环

Java 从InputStreamReader读取字节进入无限循环,java,sockets,inputstream,outputstream,Java,Sockets,Inputstream,Outputstream,我有一个测试失败了,因为从InputStreamReader读取字节将进入无限循环 @Test public void testSingleRequest() throws IOException { Server server = new Server(9000, 100); new Thread(server).start(); Socket clientSocket = new Socket("localhost", 9000);

我有一个测试失败了,因为从InputStreamReader读取字节将进入无限循环

@Test
public void testSingleRequest() throws IOException {
        Server server = new Server(9000, 100);
        new Thread(server).start();
        Socket clientSocket = new Socket("localhost", 9000);
        OutputStream out = clientSocket.getOutputStream();
        InputStream in = clientSocket.getInputStream();
        String payload = "a";
        byte[] load = buildPushPayload(payload);
        out.write(load);
        byte[] response = IOUtils.toByteArray(in);
        server.stop();

        assertEquals(0, response[0]);


    }
这是写入InputStream的代码

byte[] resp = buildPushResponse();
output.write(resp);

private byte[] buildPushResponse() throws UnsupportedEncodingException {
        ByteBuffer buffer = ByteBuffer.allocate(1);
        buffer.order(ByteOrder.BIG_ENDIAN);
        buffer.putInt(0);
        return buffer.array();
    }
服务器和客户端都写入clientSocket输入输出流。
我似乎不明白为什么会出现无限循环?

你在这里缺少的是如何知道何时停止阅读。您正在调用
IOUtils.toByteArray(in)
,它将一直读取到文件的末尾,而这永远不会发生(除非另一端关闭其套接字的末端)

在处理完整的消息包之前,您可以使用一些方案来了解作为消息包从套接字读取的字节数。例如,您可以说所有数据包都是8个字节(在这种情况下,您的read调用将指定读取8个字节),您可以说第一个字节是数据包中的字节数,您可以说数据包是可变长度的,并且以回车字节终止

一旦您读取了一个数据包,您通常会处理该数据包,然后返回读取另一个数据包或关闭套接字(如果您已全部读取完毕)

下面是一个很好的套接字编程示例:

在这种情况下,他们使用行尾标记终止数据包或消息-他们使用
DataInputStream.readUTF(socket)
一次读取一行文本


我认为“无限循环”是一个错误的术语。我认为testSingleRequest阻塞了
IOUtils.toByteArray(in)
-您要求将整个流转换为字节数组。因此,toByteArray正在等待inputstream为EOF。您没有告诉它要读取多少字节,并且套接字仍然打开。相反,您可能需要签入。available(),并读取那么多字节。如果您正在寻找基于消息的套接字,您可能希望尝试WebSocket。@Jamie我是新手,您能在这里帮助我编写代码吗。您是否建议
while(in.available()){byte[]response=IOUtils.toByteArray(in);}
我还应该关闭服务器输出流以使客户端无法使用输入流吗?这里没有
InputStreamReader
。也没有任何无限循环。您不向
InputStream
写入字节,也不从
读取器
读取字节:您读取字符;此协议不包含c字符,它包含二进制数据。当你使用错误的术语并做出错误的声明时,很难理解你在说什么。你应该使用
DataInputStream
。是的,你应该在发送方关闭输出流,否则你将永远不会在接收方收到EOS。但是你可以n扔掉所有这些代码并使用
newdataoutputstream(socket.getOutputStream()).writeInt(0)
int resp=newdatainputstream(socket.getInputStream().readInt())
分别。此代码将在流的末尾永远循环,因为它不能正确地处理
EOFEException
,即通过
中断
。修改!我愚蠢地遵循了我建议的站点中的示例。要正确地执行此操作,您必须单独捕获
EOFEException
,因为您可能不想记录它,一个d然后是
IOException
,您可能确实想记录它。糟糕的链接。捕获并打印异常,然后代码继续运行,就好像它们从未发生过一样。它无法从
readLine()检查
null
.EOS问题如上所述。冗余关闭。在构造函数中执行阻塞I/O。
Socket
作为具有
ServerSocket
系统的同一类的数据成员。in关闭。
ServerSocket
从未关闭。真正糟糕的代码。不要使用这些tinpot站点。
server = new ServerSocket(port); 
socket = server.accept(); 

// Create a DataInputStream object that takes input from the socket
in = new DataInputStream(new BufferedInputStream(socket.getInputStream())); 

String message = ""; 

// reads messages from client and prints them
// The loop exits if the message "Over" is received.
try
{ 
    while (!"Over".equals(message))
    { 
        message = in.readUTF(); 
        System.out.println(message); 
    }
}
catch(IOException i) 
{ 
    // handle error
} 
// close connection 
socket.close(); 
in.close();