2016-11-20 21 views
-3

我试图做一个简单的TCPIP客户端和服务器(为了测试目前都在同一个服务器上)程序。服务器读取请求并发回请求的确认。 我一直坚持了两个问题BufferedReader.read()在传入数据中需要null,并且在结束时不返回-1

  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(); 
     } 
} 
+1

这里没有什么支持标题中关于要求输入为空的标题声明。 – EJP

回答

1

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

BufferedReader读取字符。期。

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

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

如果要测试-1,请关闭相应的套接字。

+0

我正在发送数据'hi'。所以它应该给我'h','i'和-1?它没有返回-1。你有没有看到它没有的原因? – adarsh

+0

@ libemv.so.1.0.1 - 检查此答案的最后一行。它会返回你读取字符的整数值。您需要关闭套接字才能检测到-1。 –

+0

您的意思是关闭客户端套接字?是的,我试过了。当我杀死客户端程序时,我会看到在另一端收到的数据。但我的目标是始终得到服务器的响应,所以我不能杀死客户端? – adarsh

-1

BufferedReader.read()在输入数据需要空

不,不,并没有什么在你的问题,支持这一说法。

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

不,它不是。它应该在流结束时返回-1 查看Javadoc。

当对端关闭其端点时,会发生套接字流的结束。同行没有结束他的目标,因为它正在等待回应。因此读取请求直到流结束没有任何意义。您需要应用程序协议来定义何时停止读取请求。这可以像一条线一样简单,也可以像XML一样复杂。

注意不要这样写代码,几乎每个语句都要使用try/catch。取决于之前try块中代码成功的代码必须位于同一个try块内。开始练习,你会发现你通常只需要一个方法中的零个,一个或偶尔两个try块。

相关问题