0

I have implemented gcdasynsocket in my app and performing multiple write operations. The delegate didWriteDataWithTag is called twice but didreaddata is called only once (ie) for only one write operation.

 -(void)connectToHost:(NSString*)ip andPort:(NSString*)port
 {
    if(![asyncSocket isConnected])
    {
      dispatch_queue_t mainQueue = dispatch_get_main_queue();
      asyncSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:mainQueue];
      NSError *error = nil;
      uint16_t portNumber = (uint16_t)[port integerValue];
      if (![asyncSocket connectToHost:ip onPort:portNumber withTimeout:-1 error:&error])
     {
        NSLog(@"Error connecting: %@", error);

     }
     else
     {
        NSLog(@"Connecting...");
     }
}} 

GCDasyncsocket delegate methods

-(void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port
{
  NSLog(@"connected to host");
  [asyncSocket writeData:dataToBeWritten1 withTimeout:-1 tag:1000];
  [asyncSocket writeData:dataToBeWritten2 withTimeout:-1 tag:2000];
}

-(void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag
{
  [asyncSocket readDataWithTimeout:-1 tag:tag];
}  

-(void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
{
   if (tag==1000)
  {
     NSLog(@"didReadData and tag-----%@-----%ld",data,tag);
     [asyncSocket readDataWithTimeout:-1 tag:2000];

  }
  else if(tag==2000)
 {
    NSLog(@"didReadData and tag-----%@-----%ld",data,tag);
    [asyncSocket readDataWithTimeout:-1 tag:1000];
 }
}

I am not sure what is going wrong. Please help me to fix the issue

Karthick
  • 382
  • 1
  • 3
  • 23
  • change this [asyncSocket readDataWithTimeout:-1 tag:1000]; to [sock readDataWithTimeout:-1 tag:1000]; – Alchi Apr 28 '17 at 09:28

1 Answers1

0

I think you're getting tripped up by the inner workings of the TCP protocol. TCP is a stream-based protocol, not a message-based protocol. In other words, it guarantees that bytes will arrive in the exact same order they were sent, but there are no guarantees about how those bytes will be grouped into packets or read operations.

Specifically, I suspect your two writes are being aggregated, either in the transmitter or receiver, into a single read. In other words, this behavior is entirely normal and expected.

You'll need to separate your data into logical units using some other way besides relying on every write causing exactly one read in the receiver. One common technique is to start every message with a length field that allows the receiver to not only read each message but also to know how long it is and to be able to find where the next message starts.

Here's a good explanation on how to go about doing that: Proper technique for sending multiple pieces of data of arbitrary length over TCP socket

Community
  • 1
  • 1
godel9
  • 7,340
  • 1
  • 33
  • 53