[英]TCP Approach on the iOS platform
我目前正在開發需要與服務器通信的應用程序。 我將傳輸兩種不同大小的數據包,一個用於小數據的小數據包(例如sql請求),和一個用於文件的大數據包(或文件數,當文件超過1024bytes時)。 這些數據包如下所示:
小包:
typedef struct small_packet {
int msgtype:8;
int size:16;
int following:24;
char data1[64];
char data2[64];
} packet;
大包:
typedef struct file_packet {
int msgtype:8; //For partial file packet this should be 0x02
int size:16;
int following:24;
char data1[64];
char fileBuffer[1024];
} filePacket;
我已經使用select()在C ++中編寫了服務器的基本部分。 服務器現在接受傳入的連接,並在客戶端請求時返回游戲列表。 我已經用一個用C編寫的簡單客戶端進行了測試。
我對服務器通信的協議要求如下所示:
*
* Message types:
* 0x01: Login message. Data1 is username, data2 is pw hash
* 0x02: Login accepted/failed. Data1 is 1 for accept or 0 for not accepted
* 0x03: New user. Data1 is username, data2 is pw hash
* 0x04: New user accepted/failed. Data1 is 1 for accept and 0 for error
* 0x05: Friend list request. Data1 is username and data2 should be 0
* 0x06: Friend list header. Data1 is username and data2 should be 0
* 0x07: Friend list packet. Data1 is username, data2 is 0
* 0x08: Game list request. Data1 is username, data2 is 0
* 0x09: Game list header. Data1 is username, data2 is game id
* 0x0A: Game list packet. Following is gameID, data1 is randomness (0 or 1, first bit), data2 is players (divided by semicolon)
* 0x0B: Friend add. Data1 is username, data2 is friend username
* 0x0C: Random game add. Data1 is username, data2 is 0
* 0x0D: Friend game add. Data1 is username, filebuffer holds friends' usernames, divided by semicolons
* 0x10: File add. Data1 is username, data2 is game id
* 0x11: File request. Data1 is username, data2 is game id
* 0x12: File header. Data1 is turn number, data2 is game id
* 0x13: File part. Data1 is 0, filebuffer is filepart
*
現在到了棘手的部分。 我應該采用哪種方法為iOS平台進行套接字編程? 現在,我有一個CFRead / WriteStreamRef和NSInput / OutputStream套接字通信器類,該類具有用於切換eventCodes(例如NSStreamEventHasBytesAvailable)的流功能。 這似乎不太好用。 我做錯了什么,或者我對請求的響應太慢或阻止讀取有麻煩。 無論哪種方式,現在我只在請求游戲列表時得到0x09答復。 其余的或者永遠不會被客戶端接收,或者因為程序已經超出了讀取范圍而被丟棄(我不知道如何)。
我正在考慮切換到出色的CocoaAsyncSocket API,但是重寫我的代碼並不是很誘人。
有沒有一種方法可以為iPhone編寫一個簡單的TCP客戶端,該客戶端不會阻塞,並接收可以轉換為C樣式結構的數據? 我是否必須重新定義我的結構,或者甚至對數據使用其他內容? 我會喜歡示例或良好的鏈接(並相信我,我很高興!)。
任何幫助都非常感謝!
您可能會閱讀有關使用CocoaAsyncSocket的簡短介紹 。
您可以通過以下方式輕松建立連接:
GCDAsyncSocket *socket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
連接到您的服務器:
NSError *err = nil;
if (![socket connectToHost:@"yourserverip" onPort:80 error:&err]) // Asynchronous!
{
// If there was an error, it's likely something like "already connected" or "no delegate set"
NSLog(@"I goofed: %@", err);
}
現在將您的結構放入NSData中:
NSData *myData = [NSData dataWithBytes:&myFilePacket length:sizeof(myFilePacket)];
最后發送您的數據:
[socket writeData:myData withTimeout:-1 tag:1];
CocoaAsyncSocket還提供了許多有用的回調方法,例如:
- (void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag
或者對於傳入的數據包,您可以將NSData強制轉換回struct:
- (void)socket:(GCDAsyncSocket *)sender didReadData:(NSData *)data withTag:(long)tag
{
filePacket packet;
[data getBytes:&packet length:sizeof(packet)];
}
等等...看一下頭文件...
是的,就是這么簡單。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.