在我的基於TCP套接字的服務器上,我通過流發送數據包,其中數據包由一個標頭指定數據包中的字節數,然後是該字節數。對於那些熟悉Erlang的人,我只需設置{packet,4}選項。在iOS方面,我有一些代碼看起來是這樣的,假設我想找出流的大小此消息:CocoaAsyncSocket和從套接字讀取數據
[asyncSocket readDataToLength:4 withTimeout:-1 tag:HEADER_TAG];
這工作正常及以下的委託方法調用回調函數:
onSocket:didReadData:withTag:
我圖下一邏輯步驟是找出流的大小,以及我做到這一點與:
UInt32 readLength;
[data getBytes:&readLength length:4];
readLength = ntohl(readLength);
後硬編碼的在服務器側12個字節的串,讀數長度確實我ndeed在客戶端也讀了12,所以迄今爲止都是很好的。我繼續執行以下:
[sock readDataToLength:readLength withTimeout:1 tag:MESSAGE_TAG];
此時雖然回調onSocket:didReadData:withTag:
不再調用。相反超時在讀正在發生,可能是因爲我沒有處理的正確讀取,此委託方法被調用:
- (NSTimeInterval)onSocket:(AsyncSocket *)sock shouldTimeoutReadWithTag:(long)tag elapsed:(NSTimeInterval)elapsed bytesDone:(NSUInteger)length
所以在總體上,服務器發送16個字節,4字節的報頭和12字節二進制流。
我相信這個錯誤是關於我如何使用CocoaAsyncSocket。在瞭解其尺寸後,閱讀其餘部分流程的正確方法是什麼?
**更新**
我改變了我的客戶,它似乎現在工作。問題是,我不明白新解決方案的readDataToLength的意義。這是我改變了我最初的念想:
[socket readDataWithTimeout:-1 tag:HEADER_TAG];
現在,在我的回調,我只是做到以下幾點:
- (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag {
if (tag == HEADER_TAG) {
UInt32 readLength;
[data getBytes:&readLength length:4];
readLength = ntohl(readLength);
int offset = 4;
NSRange range = NSMakeRange(offset, readLength);
char buffer[readLength];
[data getBytes:&buffer range:range];
NSLog(@"buffer %s", buffer);
//[sock readDataToLength:readLength withTimeout:1 tag:MESSAGE_TAG];
} else if (tag == MESSAGE_TAG) {
//[sock readDataToLength:4 withTimeout:1 tag:HEADER_TAG];
}
}
所以一切都進來爲一體,有效載荷原子。也許這是因爲Erlang {packet,4}的工作原理。我希望是。否則,readDataToLength有什麼意義?沒有辦法在客戶端事先知道消息的長度,那麼使用該方法的好用例是什麼?