簡體   English   中英

使用套接字從服務器線程中的套接字讀取數據

[英]read data from socket in server thread using sockets

該應用程序具有客戶端和服務器線程。 客戶端線程正常工作。 從服務器讀取另一個應用程序的客戶端向我的應用程序發送的內容時出現問題。

實施此服務器有兩個要求

  1. 我需要使用UTF-16LE編碼
  2. 我不能使用readLine,我只需要使用read byte / s

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

這是服務器的代碼

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

有時,當我嘗試讀取服務器從客戶端接收的數據時會收到超時。

謝謝你的幫助

答案的問題不是一些神話般的EOF字符,而是您忽略了讀取計數。 它應該是

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

我曾經處理過類似的問題。 我需要使用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)

看起來以某種方式“骯臟”地來回轉換數據,但對我而言,它工作得很好。

最后,對我有用的是:

  1. 我總是分配大小為1024的緩沖區,而不使用Ata注意到的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();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM