2016-03-07 132 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