【问题标题】:BufferedReader.read() requiring null in incoming data and not returning -1 on endingBufferedReader.read() 在传入数据中需要 null 并且在结束时不返回 -1
【发布时间】:2016-11-20 12:43:57
【问题描述】:

我正在尝试做一个简单的 TCPIP 客户端和服务器(为了测试,现在两者都在同一个服务器中)程序。服务器读取请求并发送回对请求的确认。 我遇到了两个问题

  1. 据我了解 BufferedReader.read() 应该读取字节 按字节计算,当没有更多数据可供读取时返回 -1。我愿意 看不到读数发生

  2. BufferedReader.read() 永远不会完成读取循环。

为了解决1,当客户端发送请求时,我附加了一个空字符。现在我看到读取正在发生,但如果读取循环仍然等待更多数据,它不会出现。 (客户端程序中的第 96 行)。

为了解决 2,对于 read(),我停止检查 -1,并开始检查 > 0。 (服务器程序中的第 75 行)。

有人能解释一下为什么会有这种行为吗?

服务器程序

import java.net.*;
import java.io.*;
import java.util.concurrent.TimeUnit;

class TCPServer
{
        ServerSocket serverSocket;
        Socket clientSocket;
        DataInputStream is;
        DataOutputStream os;
        BufferedReader br;
        int Port;

        TCPServer( int Port)
        {
                this.Port = Port;
                try
                {
                        serverSocket = new ServerSocket( Port );
                }
                catch( Exception E )
                {
                        System.out.println( "Exception Socket : " + E );
                }
                System.out.println( "Server socket created" );

                try
                {
                        clientSocket = serverSocket.accept();
                }
                catch( Exception E )
                {
                        System.out.println( "Exception accept : " + E );
                }
                System.out.println( "Client socket created and binded" );
        }

        public void initInOutStream()
        {
                try
                {
                        is = new DataInputStream( clientSocket.getInputStream() );
                        br = new BufferedReader( new InputStreamReader( is ) );
                }
                catch( Exception E )
                {
                        System.out.println( "Exception InputStream : " + E );
                }
                System.out.println( "input stream stream created" );
                try
                {
                        os = new DataOutputStream( clientSocket.getOutputStream() );
                }
                catch( Exception E )
                {
                        System.out.println( "Exception OutputStream : " + E );
                }
                System.out.println( "output stream stream created" );
        }

        public void processTCPServer()
        {
                String clientRequest = null;
                String ServerResponse = null;
                byte[] clientRequestArray = {};
                try
                {
                        int intvalofchar = 0;
                        initInOutStream();
                        while( true )
                        {
                                StringBuilder sb = new StringBuilder( 512 );
                                System.out.println( "Waiting for request " );
                                while( ( intvalofchar = br.read() ) > 0 )
                                //while( ( intvalofchar = br.read() ) != -1 ) 
                                        sb.append( (char) intvalofchar );
                                clientRequest = sb.toString();
                                System.out.println( "Client Request : " + clientRequest );
                                ServerResponse = "Ackn for [" + clientRequest + "]\0";
                                try
                                {
                                        os.writeBytes( ServerResponse );
                                        os.flush();
                                        System.out.println( "Sent" );
                                }
                                catch( SocketException E )
                                {
                                        System.out.println( "Exception " + E );
                                }
                        }
                }
                catch( Exception E )
                {
                        System.out.println( "Exception readLine : " + E );
                }
        }

        public static void main( String []args )
        {
                TCPServer obj = new TCPServer( 9999 );
                obj.processTCPServer();
        }
}

客户端程序

import java.net.*;
import java.io.*;

class TCPClient
{
        Socket clientSocket;
        DataInputStream is;
        DataOutputStream os;

        TCPClient( String IP, int Port)
        {
                try
                {
                        clientSocket = new Socket( IP, Port );
                }
                catch( Exception E )
                {
                        System.out.println( "Exception socket: " + E );
                }
                try
                {
                        is = new DataInputStream( clientSocket.getInputStream() );
                }
                catch( Exception E )
                {
                        System.out.println( "Exception InputStream : " + E );
                }
                try
                {
                        os = new DataOutputStream( clientSocket.getOutputStream() );
                }
                catch( Exception E )
                {
                        System.out.println( "Exception OutputStream : " + E );
                }
        }

        public void processTCPClient()
        {
                String clientRequest = null;
                String serverResponse = null;
                try
                {
                        while( true )
                        {
                                clientRequest = getData();
                                System.out.println( "Send [" + clientRequest + "]");
                                try
                                {
                                        os.writeBytes( clientRequest );
                                }
                                catch( Exception E )
                                {
                                        System.out.println( "Exception writeBytes : " + E );
                                }
                                System.out.println( "Data sent " + clientRequest );
                                System.out.println( "Waiting for response " );
                                try
                                {
                                        BufferedReader brs = new BufferedReader( new InputStreamReader( is ) );
                                        int intvalofchar = 0;
                                        StringBuilder sb = new StringBuilder( 512 );
                                        while( ( intvalofchar = brs.read() ) > 0 )
                                                sb.append( (char) intvalofchar );
                                        serverResponse = sb.toString();
                                        System.out.println( "Server Response : " + serverResponse );
                                }
                                catch( Exception E )
                                {
                                        System.out.println( "Exception readLine : " + E );
                                }
                        }
                }
                catch( Exception E )
                {
                        System.out.println( "Exception readLine : " + E );
                }
        }

        public String getData()
        {
                BufferedReader br = new BufferedReader( new InputStreamReader( System.in ) );
                String request = null;
                while( true )
                {
                        System.out.println( "Enter : " );
                        try
                        {
                                request = br.readLine();
                        }
                        catch( Exception E )
                        {
                                System.out.println( "Exception readLine " + E );
                        }
                        return request+"\0";
                        //return request;
                }
        }
        public static void main( String[] args)
        {
                TCPClient obj = new TCPClient( "localhost", 9999 );
                obj.processTCPClient();
                obj.getData();
        }
}

【问题讨论】:

  • 这里没有任何内容支持标题中关于在输入中要求 null 的标题声明。

标签: java sockets network-programming bufferedreader


【解决方案1】:

我的理解 BufferedReader.read() 应该读取字节 byte 并在没有更多数据可供读取时返回 -1。我不 看到正在发生的阅读

BufferedReader 读取字符。期间。

BufferedReader.read() 永远不会完成读取循环。

它会一直循环执行(谈论你的代码),直到底层流的读取方法返回 -1,表示流结束。

如果要测试-1,关闭对应的socket。

【讨论】:

  • 我正在发送数据“嗨”。所以它应该给我'h','i'和-1?它没有返回-1。你有什么理由不这样做吗?
  • @libemv.so.1.0.1 - 检查此答案的最后一行。它会返回您读取的字符的整数值。您需要关闭套接字才能检测到 -1。
  • 您的意思是关闭客户端套接字吗?是的,我已经尝试过了。当我杀死客户端程序时,我会看到另一端收到的数据。但我的目标是始终从服务器获得响应,这样我就不能杀死客户端?
  • @libemv.so.1.0.1 - 我建议你实现一个替代版本的通信协议,在发送消息之前,你需要提供消息的长度!您目前正在做的事情不会帮助您实现您想要实现的目标!
  • 感谢您的宝贵时间。我很感激。无论如何,我会在放弃之前再看一段时间。 ?
【解决方案2】:

BufferedReader.read() 要求传入数据为空

不,它没有,您的问题中没有任何内容支持这种说法。

据我了解,BufferedReader.read() 应该逐字节读取并在没有更多数据可供读取时返回 -1。

不,不是。它应该在流结束时返回 -1 请参阅 Javadoc。

当对等端关闭其端时,套接字上的流结束。对等方尚未关闭其端,因为它正在等待响应。所以读取请求直到流结束是没有意义的。您需要一个应用程序协议来定义何时停止读取请求。这可以像一行一样简单,也可以像 XML 一样复杂。

注意不要编写这样的代码,几乎每个语句都带有try/catch。依赖于先前try 块中代码成功的代码必须在同一个try 块内。开始练习,您会发现一个方法中通常只需要零个、一个或偶尔两个 try 块。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-02
    相关资源
    最近更新 更多