gpt4 book ai didi

c++ - iOS 平台上的 TCP 方法

转载 作者:行者123 更新时间:2023-11-28 07:17:03 27 4
gpt4 key购买 nike

我目前正在开发一个需要与服务器通信的应用程序。我要传输两种不同大小的数据包,一个小数据包用于小数据(例如 sql 请求),一个大数据包用于文件(或文件片段,当文件超过 1024 字节时)。这些数据包看起来像这样:

小包:

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 编写的简单客户端对此进行了测试。

我对服务器通信的协议(protocol)要求如下所示:

 *
* 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 风格结构的数据?我是否必须重新定义我的结构,或者甚至为数据使用其他东西?我喜欢示例或良好的链接(相信我,我已经 gooooooooooogled 了!)。

非常感谢任何帮助!

最佳答案

你可能会读到 this short intro关于使用 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 转换回结构:

- (void)socket:(GCDAsyncSocket *)sender didReadData:(NSData *)data withTag:(long)tag
{
filePacket packet;
[data getBytes:&packet length:sizeof(packet)];
}

等等...查看头文件...

是的,就是这么简单。

关于c++ - iOS 平台上的 TCP 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20070947/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com