簡體   English   中英

iOS平台上的TCP方法

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM