簡體   English   中英

Java套接字讀取輸入流而不會阻塞

[英]Java socket read inputstream without blocking

我在實現Android和IOS之間的套接字連接時遇到了一些問題。 當我使用我的應用程序連接兩個運行中的Android設備時,一切正常。 但是,當我不得不從Iphone應用程序接收一些數據時,我的readStream函數將被阻止,並且在另一部分關閉套接字后我可以接收所有數據,這樣我就無法將任何響應返回給它。 這是我用來收聽的內容:

try {
    serverSocket = new ServerSocket(5000);
    Log.d("","CREATE SERVER SOCKET");
} catch (IOException e) {
     e.printStackTrace();
}

while(state){
    try {
        if(serverSocket!=null){
            client = serverSocket.accept();
            client.setKeepAlive(true);
            client.setSoTimeout(10000);

            // LOGS
            Log.w("READ","is connected : "+client.isConnected());
            Log.w("READ","port : "+client.getPort());
            Log.w("READ","ipadress : "+client.getInetAddress().toString());



            InputStream is = client.getInputStream();

            Log.w("READ","is Size : "+is.available());

            byte[] bytes = DNSUtils.readBytes(is);
            Log.v("","-------------------------");
            for(int i=0;i<bytes.length;i++){
                Log.w("READ","bytes["+i+"] : "+bytes[i]);
            }
            Log.v("","-------------------------");

            try {
                Log.w("READ","packetType : "+bytes[4]);

                if(bytes!=null)
                    DNSUtils.getPacketType(bytes[4], bytes, client);

            } catch(Exception e){
                e.printStackTrace();
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
        Log.v("","IOException");
        ResponseERR pack = new ResponseERR();
        ResponseERR.errorMsg = "Socket TimeOut exception!";
        byte[] packet = pack.createNewPacket();

        try {
            if(client!=null){
                OutputStream out = client.getOutputStream();
                out.write(packet);
                out.flush();
                client.shutdownOutput();
                client.close();
                Log.e("READDATAFROMSOCKET","ResponseERR Send.");
            }
        } catch (Exception e1) {
            e1.printStackTrace();
        }
    }
}

這是我用來將InputStream轉換為Byte Array的函數:

public static byte[] readBytes(InputStream inputStream) throws IOException {
    // this dynamically extends to take the bytes you read
    ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream();

    // this is storage overwritten on each iteration with bytes
    int bufferSize = 1024;
    byte[] buffer = new byte[bufferSize];

    // we need to know how may bytes were read to write them to the byteBuffer
    int len = 0;
    while ((len = inputStream.read(buffer)) != -1) {
        byteBuffer.write(buffer, 0, len);
    }

    // and then we can return your byte array.
    return byteBuffer.toByteArray();
}

Iphone / Android應用程序的工作方式如下:

  • 首先,它創建Socket並將數據發送到其他設備並關閉OutputStream。
  • 第二部分是解析字節數組,然后使用相同的套接字返回響應。

有任何想法如何更改我的功能,以便我可以不阻塞地讀取輸入流?

編輯:

因此問題出在IOS端,看來Apple API需要關閉已創建套接字的兩個流:讀/寫,以便可以發送字節數組,這看起來確實很愚蠢,因為那樣,iphone應用程序無法接收並解析我的回應。

與您編輯中的注釋相反,這是您的錯,而不是蘋果的錯。 您需要重新設計API。 您的readBytes()方法將讀取流直到其結束,這僅在對等方關閉連接時發生。 如果您只想讀取一些字節, read(byte[])已經做到了,並告訴您有多少read(byte[]) ,而不需要流的結尾。 我只是拋棄這種方法。

憑借對RIM OS進行編程的經驗,我認為所有這些IO操作都應在不同的線程中執行。 將要求主UI線程使用invokeLater()類型的方法調用另一個應用程序線程,在該方法中,您檢查異步操作是否完成並采取適當的措施。 這樣,您讀取輸入流的代碼必須在單獨的線程中運行。

暫無
暫無

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

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