我在我的应用程序中实现了gcdasynsocket并执行了多次写入操作。委托didWriteDataWithTag被调用两次但didreaddata仅被调用一次(即)仅用于一次写操作。
-(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];
}
}
我不确定出了什么问题。请帮我解决问题
答案 0 :(得分:0)
我认为你正在被TCP协议的内部工作所绊倒。 TCP是基于流的协议,而不是基于消息的协议。换句话说,它保证字节将以与它们发送的完全相同的顺序到达,但不能保证这些字节将如何分组到数据包或读取操作中。
具体来说,我怀疑你的两个写入是在发送器或接收器中聚合成单个读取。换句话说,这种行为完全正常并且是预期的。
除了依赖于每次写入而导致接收器中只读取一次读取之外,您还需要使用其他方式将数据分成逻辑单元。一种常见的技术是使用长度字段启动每条消息,该字段允许接收方不仅可以读取每条消息,还可以知道它有多长,并且能够找到下一条消息的起始位置。
以下是关于如何做到这一点的一个很好的解释:Proper technique for sending multiple pieces of data of arbitrary length over TCP socket