DataInputStream / InputStream不止一次读取数据

时间:2018-03-07 14:18:05

标签: java android sockets

无法从当前输入流中多次读取数据。它连接的服务器/服务使用libevent进行事件驱动的读写操作。但是,在收到带有以下代码片段的初始数据包之后,从未收到writeEvent:

new Thread(new Runnable() {
                @Override
                public void run() {
                    try  {
                        do {
                            Log.d("Socket", "Entering a new read" + socketInputStream.available());
                            // each packet begins with a packetID, UInt32
                            int newPacketID = socketInputStream.readInt();
                            newPacketID = Integer.reverseBytes(newPacketID); // to little endian
                            int packetLength = socketInputStream.readInt();
                            packetLength = Integer.reverseBytes(packetLength);
                            byte[] payload = new byte[packetLength];
                            socketInputStream.readFully(payload);
                            Log.d("Socket", "Read: " + newPacketID);
                            Log.d("Socket", "Length: " + packetLength);
                            Log.d("Socket", "Payload: " + payload.toString());
                            payload = null;
                            //socketOutputStream.write(0);
                            //socketOutputStream.flush();
                            //socketInputStream = new DataInputStream(socket.getInputStream());
                        } while( isConnected == true );
                        Log.d("Socket", "Got away from the loop");
                    } catch(Exception exc) {
                        Log.d("Socket", "Reading exception: " + exc.getMessage());
                    }

                }
            }).start();

取消注释outputStream中的单个0字节+ flush会标记套接字再次写入,但我想知道如何在没有这种hacky方法的情况下实现相同的结果。为什么Java不允许再次读取此套接字?

是因为Thread阻止了socketInputStream在其他任何地方使用(因此允许套接字标记自己可以再次写入)?

更详细地说,服务器有一个sendBuffer,它会在每次标记套接字时尝试清空。它会写出它可以写的所有内容,然后等待新的writeevent,检查数据是否可用,如果是这种情况则开始发送。如果当前没有可写的套接字,则服务器会填充sendBuffer,直到新的写入事件可以清空它为止。

func checkForData() {
        guard canWrite == true else {
            socketWriteEvent.add() // Make sure we know when we can write again!
            return
        }
        guard sendBuffer.count > 0 else { return }
        canWrite = false

        //let maxChunkSize = 20240 > sendBuffer.count ? sendBuffer.count : 20240

        var bytesWritten = 0
        var totalWritten = 0
        repeat {
            let chunk = Array(sendBuffer[totalWritten..<sendBuffer.count])
            print("Write being executed")
            bytesWritten = tls.write(chunk, count: chunk.count)
            totalWritten += bytesWritten
            print("Still in the write loop")
        } while( bytesWritten > 0 && (totalWritten < sendBuffer.count) )

        if totalWritten > 0 {
            sendBuffer.removeFirst(totalWritten)
        }
        if bytesWritten < 0 {
            let error = tls.context.contextError()
            if error.isEmpty == false {
                print("[TLS] Error: \(error)")
            }
        }
        print("Write completed");
        socketWriteEvent.add()
   }

0 个答案:

没有答案