I'm building a small and easy to use TCP
framework in Swift 3 for macOS and iOS (someday it will support Linux). This is something new that I explore and thats why there is potential of confusion and bugs.
My internal code looks like this:
if Darwin.send(self._fileDescriptor._value, data.withUnsafeBytes { $0 }, data.count, 0)._isMinusOne() {
try Error._throw(type: .network)
}
Sending small packages is not a problem, but when I tried to send a large package my application crashed (I was trying to send 1590784 bytes at once). After that I investigated the problem and found out that I missed the limit I can pass to Darwin.send
function. I've been searching on the web to find a good answer, but unfortunately there are a few numbers I found about this specific topic (65K, 1500, etc.).
My question is what maximum buffer size should I use in Darwin.send
function to always be on the safe side?
I'm not that experienced in that particular area, so it would be nice if the answer to my question would explain why do you think the size you have chosen is the best and safest choice.
I didn't know there was a limit to the size of the buffer you can pass to send()
.
However, it is not safe to return the pointer you get as a parameter to your block in data.withUnsafeBytes
. I don't think you can guarantee it points to a valid memory region after the block returns.
You should try
let bytesSent = data.withUnsafeBytes{
return Darwin.send(self._fileDescriptor._value, $0, data.count, 0)
}
Update
I have checked the source code for withUnsafeBytes
and I can confirm that no effort is made by the method call to preserve the memory pointed to beyond the scope of the closure you pass to it. What you are trying to do is reference memory after it has been deallocated. I'm sure this is the source of your crash.