使用套接字从服务器线程中的套接字读取数据

时间:2016-03-07 14:37:33

标签: java sockets server

应用程序具有客户端和服务器线程。客户端线程正常工作。 从服务器读取其他应用程序上的客户端发送给我的应用程序时出现问题。

实现此服务器有两个要求

  1. 我需要使用UTF-16LE编码
  2. 我不能使用readLine,我只需要使用read byte / s
  3. 我尝试了很多例子,但似乎没有任何工作正常。

    这是服务器的代码

    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();
    }
    

    当我尝试读取服务器从客户端收到的数据时,有时会收到超时。

    感谢您的帮助

3 个答案:

答案 0 :(得分:1)

你的回答问题不是一些神秘的EOF角色,而是你忽略了读数。它应该是

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

答案 1 :(得分:0)

我曾经处理过类似的问题。我需要使用带有UTF-8编码字节的UTF-16获取字符串。所以我写了这个方法:

{
    "token_type":"bearer",
    "expires_in":3600,
    "scope":"wl.signin wl.offline_access wl.basic wl.skydrive wl.skydrive_update onedrive.readwrite onedrive.appfolder",
    "access_token":"EwCAAq1DBAAUGCCXc8wU/zFu9QnLdZXy+YnElFkAAeOVCOpU5J8YFnp8I1jF2AMYKDycpjKLDZ2zSvz1mlcl0VGSIyOwnMsqcAl8PnAo1YAUPV72Mqvp7ycKkI+6xB3M8lmqQJ8/MGL4vRk4Ets6P49PkhsA5dQMJOB+TxEeP9dfpqIYInoilLft6xWlDGCAAbgEtaZTrmAQcHk4zabYSYgMZlRzjyEOEkd3N9/wjSzbTyDvuOp5/d7j6m5qPWINBHLqxjlSRd62vVzz+/8wzLGCIqXRNny5lJmz+ME9Hryz8yqNY3Xt3Y768b/H9AWnLYwVYRHKlN2rmUHkvTn9e1xUGNYCrinnODx+Ah1M94egSZCfpcnuni5+dp9ERBEDZgAACPlDtNXQ+EvCUAE+jeQ/WNQuIkhyPnIJ8KdxedYNnPAJL1zYL6LZeQEv3CLEIn+PW2DKmMnY0tcO2qRJ+KLQJjYLjKnGycJlkFYujMUgmYoUxYoHuCVTO1GrQO9o83ROJCzaNIF9FG+YY9vfNUC/CJBwrBt9a0RDtPBJt4Zz6wi7BI2J1p+3xT4n5I12kGkGLcKXUevu9h3DfdBmOu57EpJpKk1ItS0aURCc5GfgyHQzj0rn2tFDOp6UDGmtPWl3Bfv0WhKVfj0w5Q2caJD9axKUhRxCbdrnxckPdFQ2bswUJ5NLQC2TQNCup7ESIYIloH52RKUy+S2kpVJpZwAjE90//R4W0zia86eap6R+EBJtA/En3PjSNMXJe0U98xtuSVZTSo3YNIXLIcs+n95vt2z5kzBAw5q7LsiEHq972vw5ijt1L/8p6sdh+TiRHT7n0LfsidXH41kj9olmAQ==","refresh_token":"MCWYiByRoP7HJxL3LSyi3Xw84RYva1l3!TIIxqoavyEmMawV3f5K0kX9YsqSjZIGjMKXhR9f4N7sY5njzwsNl3nzXSTQX25Ruc6ExH0lFVM2fwGAipLqP!IbtwSnSPgoigURfwvbgobqMjSFLu33iAM!qImWJjLZ3IOrNZ74E0vgFIGK0rgW8TCk!vu3eD5hlTQ!36RJCfCx1RqKS94Z0d1e99!xFAmR!L8VyxO4GNrHco0OzSkTb*WmJ*0QUE4hY5QSh8uXd*x*0r6kd2dsGbia7ypy5nCWJD7N*NY4t8CpFgvKEaL5E!l70XzJyfTfHDGzSyG7o*aNyRGYUwTnIXCGeCIJfj85ZmOj2IhIx9i84",
    "user_id":"a34b420ae6b20e72b2e15d5a25564c52"
}

(你设置" UTF-16LE"作为charsetName)

以某种方式看起来"脏"来回转换数据,但对我来说它完美无缺。

答案 2 :(得分:-1)

最终我的工作是:

  1. 我总是在大小为1024的情况下分配缓冲区而不使用 iStream.available()作为Ata注意到的。
  2. 经过多次尝试后,我没想到如何在“EOF”之后逃脱所有角色。我只是通过EOF拆分接收的字符串并获取字符串的第一个片段,它工作得很好。 EOF符号结束客户端的请求。
  3. 这是我最终使用的代码

    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();
    }