无法从当前输入流中多次读取数据。它连接的服务器/服务使用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()
}