2016-03-07 120 views
0

應用程序具有客戶端和服務器線程。客戶端線程正常工作。 在從服務器讀取其他應用程序的客戶端發送給我的應用程序的過程中出現問題。使用套接字從服務器線程中的套接字讀取數據

有兩個要求來實現這個服務器

  1. 我需要使用UTF-16LE編碼
  2. 我不能使用輸入行,我只需要使用讀取字節/秒

我嘗試了很多例子,但似乎沒有任何工作正常。

這裏是服務器

private static final int NUM_STATUSES = 30; 
private static final int NUM_ERRORES  = 50; 
private ServerSocket  _serverSocket; 
private Socket    _socket; 
private Handler    _handler; 
private int     _port; 

//handler of main activity 
public ServerNetworkThread() 
{ 
    setName("ServerNetworkThread"); 
} 

public void setHandler(Handler h) 
{ 
    _handler = h; 
} 

@Override 
public void run() 
{ 

    _isWorking = true; 
    try 
    { 
     _serverSocket = new ServerSocket(); 
     _serverSocket.setReuseAddress(true); 
     _serverSocket.bind(new InetSocketAddress(_port)); 

     while (_isWorking) 
     { 
      _socket = _serverSocket.accept(); 
      _socket.setSoTimeout(Consts.CLIENT_SOCKET_TIMEOUT); 

      readDataTest(); 

     } 

    } 
    catch (SocketTimeoutException e) 
    { 
     e.printStackTrace(); 
    } 
    catch (IOException e) 
    { 
     e.printStackTrace(); 
    } 

} 

private void readDataTest() throws IOException 
{ 
    //   BufferedReader inFromClient = new BufferedReader(new InputStreamReader(_socket.getInputStream(),Charset.forName("UTF-16LE"))); 
    InputStream iStream = _socket.getInputStream(); 
    InputStreamReader in = new InputStreamReader(iStream, Charset.forName("UTF-16LE")); 
    DataOutputStream outToClient = new DataOutputStream(_socket.getOutputStream()); 
    char[] buf = new char[iStream.available()]; 
    in.read(buf, 0, buf.length); 
    String request = new String(buf); 

    String responseStr = parseResponse(request); 
    byte[] response = responseStr.getBytes("UTF-16LE"); 
    outToClient.write(response); 
    outToClient.flush(); 
    outToClient.close(); 
    in.close(); 
    _socket.close(); 
    //   inFromClient.close(); 
} 

的有時候我收到的時候我試圖讀取服務器從客戶端接收數據超時的代碼。

感謝您的幫助

+0

你可以發佈stacktrace嗎? – Nadir

+0

打印我收到的東西后,我發現了一些奇怪的東西: request = BB0006 └א└א└א└א└א└א└א└א└א└א└א└א└א└א└א└ א└א└א└א└א└א 最後有很多字符不需要在那裏,也許有問題,行 char [] buf = new char [iStream.available()] ; –

+0

在'String request = new String(buf);'你正在使用UTF-8構建一個字符串,字節是從UTF-16L開始的。在構建字符串時指定字符集 – Nadir

回答

1

的問題,你的答案是不是有些神祕的EOF字符,它是你忽略了讀取計數的代碼。它應該是

int count = in.read(buf); 
if (count == -1) 
    throw new EOFException(); 
String request = new String(buf, 0, count);` 
+0

謝謝,這個解決方案適合我,謝謝! –

0

我曾經處理過類似的問題。我需要使用UTF-16編碼爲UTF-8的字節來獲取字符串。所以我寫了這個方法,這樣做:

//NOTE: 'charsetName' has to be a valid Name (see 'Charset'-Class in the API) 
public String encode(char[] data, String charsetName) 
{ 
    //Convert char[] to a String 
    String charString = String.copyValueOf(data); 
    String encoded = ""; 

    try 
    { 
     //Since there is no constructor which lets you set char[] with encoding 
     //convert your String to a byte-Array. There is a constructor which lets 
     //you set the Encoding for it. 
     byte[] bytesEncoded = charString.getBytes(charsetName); 

     //Construct a String using the encoding 
     encoded = new String(bytesEncoded, charsetName); 
    } 
    catch (UnsupportedEncodingException e) 
    { 
     e.printStackTrace(); 
    } 

    return encoded; 
} 

(您可以設定「UTF-16LE」是的charsetName)

看起來有點「髒」數據轉換來回,但對我來說非常完美。

+0

不幸的是我在之後仍然收到一些奇怪的字符。但感謝您的幫助! –

-1

到底對我有什麼工作是:

  1. 我總是在分配大小爲1024的緩衝區,而無需使用iStream.available()作爲阿塔注意到。
  2. 經過多次嘗試,我沒有想到如何在「EOF」後逃脫所有的字符。我只是通過EOF分割接收到的字符串並獲取字符串的第一個片段,它工作得很好。 EOF符號結束來自客戶端的請求。

這是我最後使用

private void readDataTest() throws IOException 
{ 
    InputStream iStream = _socket.getInputStream(); 
    InputStreamReader in = new InputStreamReader(iStream, Charset.forName("UTF-16LE")); 
    DataOutputStream outToClient = new DataOutputStream(_socket.getOutputStream()); 
    char[] buf = new char[1024]; 
    in.read(buf, 0, buf.length); 
    String request = new String(buf); 
    request = request.split(Consts.EOF)[0]; 

    String responseStr = parseResponse(request); 
    byte[] response = responseStr.getBytes("UTF-16LE"); 
    outToClient.write(response); 
    outToClient.flush(); 
    outToClient.close(); 
    in.close(); 
    _socket.close(); 
} 
+0

EOF不是數據中的字符。 – EJP

+0

是的,它可以,你可以看到我使用Consts.EOF,這個字符串是「」一個字符串表示接收到的字符串的結尾,你可以在第一篇文章的第二條評論中看到這一點。 –

+0

所以你的代碼是*發送*一些EOF字符?未顯示在任何地方 – EJP