GCDAsyncSocket - not receiving data - AsyncSocket works ok
I made an iPhone client connect to a server using GCDAsyncSocket. The server is running .Net on a Windows server. The connect is good and it sends data well too.
I then tell the client to go into receive directly after the send...
[sock readDataToData:[GCDAsyncSocket LFData] withTimeout:15 tag:1];
I also have this set up to receive:
- (void)onSocket:(GCDAsyncSocket *)sock didReadData:(NSData *)data
withTag:(long)tag
and also:
- (NSTimeInterval)socket:(GCDAsyncSocket *)sock shouldTimeoutReadWithTag:(long)tag
If I wait for the time out the time out method is called.
If I send data from the server, the timeout is not called, so I assume the client has seen something, but there is no indication of that on the client side.
I also added:
- (void)socket:(GCDAsyncSocket *)sock didReadPartialDataOfLength: (NSUInteger)partialLength tag:(long)tag
hoping I would see a partial packet but this does not get triggered either.
As I mentioned above the timeout does not trigger if I send something from the server to the client. However I would have thought it would also timeout if it hasn't received the terminator character. I also tried reading with a length of 3 but that didnt make any difference.
The GCDAsyncSocket is the the problem. AsyncSocket seems to work ok.
Maybe its the init is wrong?
dispatch_queue_t mainQueue = dispatch_get_main_queue();
asyncSocket = [[GCDAsyncSocket all开发者_Python百科oc] initWithDelegate:self delegateQueue:mainQueue]
Any ideas what I did wrong?
I put a post on the goggle code for this but there isnt any activity so not sure if I will get an answer or not.
Ideally if anyone has a sample code that the receives works that would be great! thank you!
Maybe there was something wrong with the spelling. (So this happened to me and I was searching for hours until I've seen the small difference)
GCDAsyncSocket renamed all delegate callbacks from onSocket to socket to match Apples naming style.
In your example above you have mentioned
- (void)onSocket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
rename it to
- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
This should resolve that problem.
And in my code I've had another problem, too. Be sure the object, which calls GCDAsyncSocket, is still alive while you are connecting. GCDAsyncSockets delegate is a weak reference to your object. And because its async, the delegate can become zero (autorelease, or the instance was created inside a method which is already left) while the socket is responding. As result it appears to not be called, but the class which started the socket is already deallocated from memory. This happens especially if you are using ARC together with GCDAsyncSocket.
Hope this helps
Are you sure your server is sending data terminated with just a LineFeed and not a CRLF? Or perhaps the data you are sending back from your server isn't terminated with anything? readDataToData
will wait until it hits that terminating character in the received data.
Here's the code I'm using to connect. I've stripped out what I don't think is necessary - hopefully I've not taken out anything important.
Init socket
asyncSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
Connect
[asyncSocket connectToAddress:addr error:&err]
On connection
- (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port {
connected = YES;
Sending (without timeout)
[asyncSocket writeData:dataData withTimeout:-1 tag:0];
Request to read the data
[asyncSocket readDataToData:[GCDAsyncSocket CRLFData] withTimeout:30.0 tag:0];
Data has come through (I'm just sending strings)
- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag {
NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
I had the same problem and was ready to give up. My problem was server side. In my delegate method onSocket:didAcceptNewSocket: I was calling a read on the wrong socket. This solved it.
-(void)onSocket:(AsyncSocket *)sock didAcceptNewSocket:(AsyncSocket *)newSocket
{
NSLog(@"Connection Socket connected to ipad at %@",[newSocket connectedHost]);
_ipadSocket = newSocket;
[_ipadSocket setDelegate:self];
//***This code was the faulty line. I was calling listen on sock not newSocket
[_ipadSocket readDataToData:[AsyncSocket CRLFData] withTimeout:10 tag:0];
}
I think the issue is coming from what you send. If the content contains a LF somewhere in your file, the read will end when it reads the LF. You should base64 encode before sending your file or read until a size.
Add :
[sock readDataWithTimeout:-1 tag:0];
at the end of didConnectToHost.
- (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port
{
//Your Code
[sock readDataWithTimeout:-1 tag:0];
}
I have developed almost the same code, side server ios side client vb net. From vb.net i send a file of 147 kb with metod socket.sendfile ,while in ios a use AsyncSocket so:
- (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag;
{
[sock readDataToData:[AsyncSocket CRData] withTimeout:-1 tag:0];
[dataFile appendData:data];
}
I don't have nobody problem with connect and start send/receive,but my only problem is that I receive 152 kb if I use CRData and 143 kb if I use LFData delimiter.
The answer is this how make to add delimiter in vb net when i send the file?
精彩评论