BlueSocket
BlueSocket copied to clipboard
socket.read() freezes when 4096 or multiple of 4096 bytes in socket for readout
Tested on Linux and MacOS and manifests on both.
Below is the reproduction pattern. Just copy/paste to SocketsTests.swift and run tests.
`
func testReadX4096BytesIssue() {
var data = Data()
do {
// Launch the server helper...
launchServerHelper(family: .unix)
// Need to wait for the server to come up...
#if os(Linux)
_ = Glibc.sleep(2)
#else
_ = Darwin.sleep(2)
#endif
// Create the signature...
let signature = try Socket.Signature(socketType: .stream, proto: .unix, path: path)!
// Create the socket...
let socket = try createHelper(family: .unix)
// Defer cleanup...
defer {
// Close the socket...
socket.close()
XCTAssertFalse(socket.isActive)
}
// Connect to the server helper...
try socket.connect(using: signature)
if !socket.isConnected {
fatalError("Failed to connect to the server...")
}
print("\nConnected to path: \(path)")
print("\tSocket signature: \(socket.signature!.description)\n")
_ = try readAndPrint(socket: socket, data: &data)
for count in [4095, 4097, 4096]
{
let hello = String(repeating: "a", count: count)
let bytesWritten = try socket.write(from: hello)
print("Wrote '\(bytesWritten)' bytes to socket...")
let response = try readAndPrint(socket: socket, data: &data)
XCTAssertNotNil(response)
XCTAssertEqual(response!, "Server response: \n\(hello)\n")
}
try socket.write(from: "QUIT")
print("Sent quit to server...")
// Need to wait for the server to go down before continuing...
#if os(Linux)
_ = Glibc.sleep(1)
#else
_ = Darwin.sleep(1)
#endif
} catch let error {
// See if it's a socket error or something else...
guard let socketError = error as? Socket.Error else {
print("Unexpected error...")
XCTFail()
return
}
print("testReadWriteUnix Error reported: \(socketError.description)")
XCTFail()
}
}
static var allTests = [
("testDefaultCreate", testDefaultCreate),
("testCreateIPV6", testCreateIPV6),
("testCreateUnix", testCreateUnix),
("testCreateUDP", testCreateUDP),
("testListen", testListen),
("testListenPort0", testListenPort0),
("testListenUnix", testListenUnix),
("testListenUDP", testListenUDP),
("testListenPort0UDP", testListenPort0UDP),
("testConnect", testConnect),
("testConnectTo", testConnectTo),
("testConnectToWithTimeout", testConnectToWithTimeout),
("testConnectToPath", testConnectToPath),
("testConnectPort0", testConnectPort0),
("testHostnameAndPort", testHostnameAndPort),
("testBlocking", testBlocking),
("testSetReadTimeout", testSetReadTimeout),
("testSetWriteTimeout", testSetWriteTimeout),
("testIsReadableWritableFail", testIsReadableWritableFail),
("testIsReadableWritable", testIsReadableWritable),
("testFDSetBitFields", testFDSetBitFields),
("testDomainSocketPath", testDomainSocketPath),
("testReadWrite", testReadWrite),
("testTruncateTCP", testTruncateTCP),
("testReadWriteUDP", testReadWriteUDP),
("testReadWriteUnix", testReadWriteUnix),
("testReadWriteUnix", testReadX4096BytesIssue),
]
} `
Just discovered this issue, too. It is a rather annoying blocker. My solution was to increase the readBufferSize to 5 MB, since none of my packets will be bigger and I am using Unix domain sockets, but it would be much better to use a timeout and let not block the application.