2014-02-26 121 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 [])。

相關問題