Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 alloc] 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!

like image 864
Mark Worsnop Avatar asked Jul 01 '11 13:07

Mark Worsnop


4 Answers

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

like image 181
JackPearse Avatar answered Nov 01 '22 06:11

JackPearse


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];
like image 45
Nick Bull Avatar answered Nov 01 '22 06:11

Nick Bull


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];
}
like image 3
Corey Zambonie Avatar answered Nov 01 '22 06:11

Corey Zambonie


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.

like image 1
Pascal Avatar answered Nov 01 '22 04:11

Pascal