2012-05-06 47 views
2

我有一个由客户端和服务器组成的Java应用程序。客户端向服务器发送加密命令,服务器执行它们。Java:从套接字获取多行

现在我遇到的问题是,使用我的加密算法,有时加密的命令包含“\ n”或“\ r”字符,这些字符混淆了我的服务器代码。这是因为我正在使用readLine()方法,该方法在找到行终止符时停止。我需要的是读取客户端发送到一个字符串中的所有字符的方法。

这里是我的代码:

public void run(){    
     System.out.println("Accepted Client!"); 

     try{         
      in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream(), "ISO8859_1")); 
      out = new PrintWriter(new OutputStreamWriter(clientSocket.getOutputStream(), "ISO8859_1")); 

      String clientCommand = null; 

      while(RunThread){      
       // read incoming stream 
       do{ 
        clientCommand = in.readLine(); 
       }while(clientCommand == null); 

       //decrypt the data 
       System.out.println("Client: " + clientCommand); 

       if(clientCommand.equalsIgnoreCase("quit")){ 
        RunThread = false; 
       }else{ 
        //do something 
        out.flush(); 
       } 
      } 
     }catch(Exception e){ 
      e.printStackTrace(); 
     } 
    } 

一切我已经试过(各种形式使用read()函数的嵌套循环)没有奏效。我会欢迎任何帮助或建议。感谢大家!

+0

只是不要使用文本,Reader/Writer,而是使用Input/OutputStream,并读取二进制数据(字节)。在上面的代码中,编码可能会造成严重破坏。 –

回答

1

我在您发布的代码中看不到加密,但通常依赖分隔符不是一个好主意。

在发送二进制数据时,应该在数据流中加上数据的长度,然后确切地知道需要多少字节(以及消息何时结束)。这样做的效率更高寻找换行符。

+0

谢谢!那么你如何从代码的角度去做呢?我想我在这里的真正斗争是等待和接受应该如何工作。我要么以无限循环结束,要么我没有收到任何东西。我如何知道数据何时进入,以及如何计算出有多远? – Jason

+0

@Jason基本上,你的循环会调用read()来获得一个包含消息长度的字符(直到消息有效)。然后你可以再次调用read来读取消息到字节数组中。从那里你可以解密或将其转换为字符串。 – takteek

+0

你真棒。那就是诀窍,现在它运作得很好。谢谢! – Jason

0
// read incoming stream 
do{ 
    clientCommand = in.readLine(); 
}while(clientCommand == null); 

那== NULL似乎是错误的

尝试

String line = null; 
do { 
    line = in.readLine(); 
    clientCommand += line 
} while (line != null); 
+0

该代码看起来好像它会工作到一个点,除了我会失去任何换行符或返回字符。我需要所有的字符来解密我的字符串,简单地附加一个“\ n”将不起作用,因为它最初可能是一个“\ r \ n”或甚至是“\ r”。 。 。 – Jason

0

有一件事你必须做的,用TCP/IP工作时,是实际的消息之前发送的消息长度。应用程序级别无法预见TCP级别传递给命运的程序包大小。所以,在你的消息之前,你必须发送一个包含消息大小的头部,而命运只读取这些字节。 关于readLine(),我认为最好使用另一种方式,如流。不久,一个建议:

Socket oSocket = new Socket(sAddress, iPort); 
    PrintWriter out = new PrintWriter(oSocket.getOutputStream(), true); 
    BufferedReader in = new BufferedReader(new InputStreamReader(oSocket.getInputStream())); 
+0

'这是一个很好的建议;但是,我仍然迷失。实际将数据接收到字符串后面的物流是什么? – Jason

0
do{ 
    clientCommand = in.readLine(); 
} while(clientCommand == null); 

这是没有意义的。 readLine()仅在流结束时返回null,所以您告诉Java在流结束时无限循环。我甚至不明白为什么有一个循环。你不想忽略来自客户端的任何输入,你想要处理它。您应该从客户端读取一行,执行它并读取另一行。重复,直到null,然后关闭插座。