繁体   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