-
Notifications
You must be signed in to change notification settings - Fork 3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Read stream never completes #89
Comments
You should send the large size file using write data method only once,and then reading small data in // sender data client
{
} // receive data client
}
} I use this to send large size file successfully.You can refer it.I hope it will help you. At 2012-10-12 17:33:04,basvankuijck notifications@github.com wrote: I am playing with GCDAsyncSocket (MRC / iOS6) for a while. Here's some of my code: WRITING I hope this is enough code to see what I'm doing wrong or maybe this is a bad practice for writing/reading large chunks of data. ¡ª |
I was under the assumption that |
I also was under the assumption that GCDAsycSocket did the 'packet chunking' for me, but I am getting the same result you are. Under heavy load, and not all of the time, readDataToLength never completes even though tcpdump shows the data as being received and ack'd back to the sender. Did you ever resolve this? KCC |
Ugh, please tell me there is a solution to this. I am now experiencing the exact same thing. If I write out the NSData to disk after the last didRead, it's about one "read size" away from completion. |
Did someone in this thread find a solution/workaround to this issue? |
The only solution is to do a generic read ( readDataWithTimeout ) and do your own message aggregation with whatever length data you get. |
Chiming back in on this. Here we are 5 years later and it's still happening, though it only seems to happen to me when I'm using TLS. It seems to always be about 8 bytes away from completion regardless of how small I chunk the data reads. |
When using GCDAsyncSocket, we have noticed that our reads can sometimes hange before all of the data is read. The end result is that our read times out and the connection is closed. This issue seems to be similar to ones that others have reported (e.g. robbiehanson#89, robbiehanson#185, robbiehanson#225, and possibly The problem seems to be that `doReadData` can get into a state where the method finishes, we have not read all of the bytes for the current read, but we do not resume the `readSource`, preventing `doReadData` from being triggered again. Here is a confusing but valient attempt to explain the issue: When we enter `doReadData` we calculate the `estimatedBytesAvailable`. This value includes how much data we think is available on the socket plus how much data is available on some of our internal buffers. If that number is greater than 0, we will initialize a `waiting` flag to false. We then proceed to read from the socket, since there are bytes available. This is where it gets tricky. We calculate the number of `bytesToRead` from the socket by taking the minimum of A.) The `estimatedBytesAvailable` plus 16 kb or B.) The remaining bytes of the current read. The trickiness comes from the fact that when `B` is larger than `A` and the socket has the extra 16kb all ready to be read, then the call to `SSLRead` will return with no error. This is problematic because we rely on a result of `errSSLWouldBlock` in order to toggle the `waiting` flag to true. Finally, when we reach the end of the `doReadData` method and we have not completed the current read and `waiting` is not set to true. Because `waiting` is false, we do not attempt to resume the readSource. Since the `readSource` may be in a suspended state, there is nothing to trigger another call to `doReadData`. This results in what looks like a "hung" or "frozen" state from the client. Even though data is flowing to our socket, we never finish reading it out. This fix in this commit, as simple as it is, just sets `waiting` to true in the case of the "read to length" and "read to term" cases where we are expecting to see more data. Another possible fix could be pass the remaining bytes to read to SSLRead to trigger the `errSSLWouldBlock`. The issue with this is that I don't fully understand the logic around `optimalReadLengthWithDefault:shouldPreBuffer:`. It may be more desirable to not trigger that error and just wait until the readSource says that there is more available from the file descriptor. Another possible fix would be in how we initially set `waiting`. Instead of setting it to `!hasAvailableBytes`, you could change it to `(estimatedBytesAvailable + [preBuffer availableBytes]) < (currentRead->readLength - currentRead->bytesRead). I am not sure if this is desireable and I would neet some input from the maintainers.
When using GCDAsyncSocket, we have noticed that our reads can sometimes hange before all of the data is read. The end result is that our read times out and the connection is closed. This issue seems to be similar to ones that others have reported (e.g. robbiehanson#89, robbiehanson#185, robbiehanson#225, and possibly The problem seems to be that `doReadData` can get into a state where the method finishes, we have not read all of the bytes for the current read, but we do not resume the `readSource`, preventing `doReadData` from being triggered again. Here is a confusing but valient attempt to explain the issue: When we enter `doReadData` we calculate the `estimatedBytesAvailable`. This value includes how much data we think is available on the socket plus how much data is available on some of our internal buffers. If that number is greater than 0, we will initialize a `waiting` flag to false. We then proceed to read from the socket, since there are bytes available. This is where it gets tricky. We calculate the number of `bytesToRead` from the socket by taking the minimum of A.) The `estimatedBytesAvailable` plus 16 kb or B.) The remaining bytes of the current read. The trickiness comes from the fact that when `B` is larger than `A` and the socket has the extra 16kb all ready to be read, then the call to `SSLRead` will return with no error. This is problematic because we rely on a result of `errSSLWouldBlock` in order to toggle the `waiting` flag to true. Finally, when we reach the end of the `doReadData` method and we have not completed the current read and `waiting` is not set to true. Because `waiting` is false, we do not attempt to resume the readSource. Since the `readSource` may be in a suspended state, there is nothing to trigger another call to `doReadData`. This results in what looks like a "hung" or "frozen" state from the client. Even though data is flowing to our socket, we never finish reading it out. This fix in this commit, as simple as it is, just sets `waiting` to true in the case of the "read to length" and "read to term" cases where we are expecting to see more data. Another possible fix could be pass the remaining bytes to read to SSLRead to trigger the `errSSLWouldBlock`. The issue with this is that I don't fully understand the logic around `optimalReadLengthWithDefault:shouldPreBuffer:`. It may be more desirable to not trigger that error and just wait until the readSource says that there is more available from the file descriptor. Another possible fix would be in how we initially set `waiting`. Instead of setting it to `!hasAvailableBytes`, you could change it to `(estimatedBytesAvailable + [preBuffer availableBytes]) < (currentRead->readLength - currentRead->bytesRead). I am not sure if this is desireable and I would neet some input from the maintainers.
Add the following code on line 5480 for GCDAsyncSocket.m file.
This made all the difference for me! |
This issue has been marked as stale, it will be closed automatically if there is no further activity. |
I am playing with GCDAsyncSocket (MRC / iOS5.1) for a while, especially with "large" files (5 - 10 mb). Unfortunately sometimes the read stream is never completed (e.g. it gets stuck) just a few bytes at the end of the stream; the
didReadPartialDataOfLength:
stops giving me information and thedidReadData
is not fired at all.Here's some of my code (for both writing / reading examples the connection between the host and client have been established)
WRITING
READING
I hope this is enough code to see what I'm doing wrong or maybe this is a bad practice for writing/reading large chunks of data.
The text was updated successfully, but these errors were encountered: