0

アプリに gcdasynsocket を実装し、複数の書き込み操作を実行しました。デリゲート didWriteDataWithTag は 2 回呼び出されますが、didreaddata は 1 回だけ (つまり、1 回の書き込み操作に対して) 呼び出されます。

 -(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 デリゲート メソッド

-(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];
 }
}

何が問題なのかわかりません。問題を解決するのを手伝ってください

4

1 に答える 1

0

TCP プロトコルの内部の仕組みにつまずいていると思います。TCP は、メッセージ ベースのプロトコルではなく、ストリーム ベースのプロトコルです。つまり、バイトが送信されたのとまったく同じ順序で到着することが保証されますが、それらのバイトがどのようにパケットまたは読み取り操作にグループ化されるかについては保証されません。

具体的には、送信機または受信機のいずれかで、2 つの書き込みが 1 つの読み取りに集約されていると思われます。つまり、この動作は完全に正常であり、予期されたものです。

レシーバーで正確に 1 つの読み取りを引き起こすすべての書き込みに依存する以外に、他の方法を使用してデータを論理単位に分離する必要があります。一般的な手法の 1 つは、すべてのメッセージを長さフィールドで開始することです。これにより、受信者は各メッセージを読み取るだけでなく、メッセージの長さを把握し、次のメッセージの開始位置を見つけることができます。

これを行う方法についての良い説明は次のとおりです。TCPソケットを介して任意の長さの複数のデータを送信するための適切な手法

于 2013-11-15T07:49:21.430 に答える