2014-02-26 64 views
2

我有一个简单的TCP服务器,可以在基于文本的协议上进行通信。我从客户端接收数据,然后发送OK/NOT OK响应。什么是从Java套接字读取正确的方法?

该协议具有以下格式:

<KEYWORD> <DATA>\r\n

<KEYWORD> ASCII文本,上长度没有限制,只是它是ATLEAST 1.

<DATA>大多只是ASCII文本,可以是二进制数据,在这种情况下,首先发送长度(以允许内部的\ r \ n序列)

每个命令都以\ r \ n结尾,并且<KEYWORD>和之间总是有空格

我试图通过字节读取字节,如:

ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
InputStream is = socket.getInputStream();  
while (tmp != ' '){ 
    baos.write(in.read()); 
} 

但是我遇到了一个问题,即in.read()返回-1,如果它没有读什么和我ByteArrayOutputStream被这种-1s淹没(和不只是-1,在调试中我看到-3,-32,3等等)。我的解决办法是把它包在if,就像这样:

while (tmp != ' '){ 
    byte tmp = in.read(); 
    if(tmp >= 'A' && tmp <='z'){ 
     baos.write(tmp); 
    } 
} 

,但似乎像一个适当的方式做到这一点不,因为这也读大写和小写字母之间的任何东西。如果我决定排除^_,那么我必须添加&& tmp != '^' && tmp != '_'

有人能指点我吗?

回答

2

的这里的问题是,InputStream.read()返回INT不是byte。这使得-1可以与位模式0x11111111区分开来,该位模式也是有符号的字节-1。你应该使用

int tmp = in.read(); 

所以你可以区分这两个值。

0

为什么不逐行阅读,因为你期望一个文本流?

BufferedReader br = new BufferedReader(new InputStreamReader(is)); 
String line = null; 
while((line = br.readLine())!= null){ /* TODO */ } 

当然,在同一个套接字中处理文本命令和二进制数据会给你一些头痛的问题。例如,FTP使用两个端口。

您可以发送base64编码的二进制数据,因为他们对文本的网络协议,可以处理二进制数据(HTTP,SMTP ECC)

0

你应该阅读,直到直播结束,这是由-1标志着做。 使用一个忽略串轻松过滤掉字符

性能方面的原因
String ignore = "_^"; 
int data = in.read(); 
while (data != -1) { 
    if (ignore.indexOf((char)data) != -1) 
     baos.write(data); 
    data = in.read()); 
} 

注意你应该使用缓存读取。请参阅InputStream.read(byte [])。

相关问题