如何使用 CFNetwork 从套接字获取字节数组?

发布于 2024-09-05 22:48:29 字数 2396 浏览 4 评论 0原文

我正在开发一个针对 iPad 的项目,它是一个小程序,我需要它与另一个在 Windows 上运行并充当服务器的软件进行通信;所以我为 iPad 创建的应用程序将是客户端。

我正在使用 CFNetwork 进行套接字通信,这是我建立连接的方式:

char ip[] = "192.168.0.244";
NSString *ipAddress = [[NSString alloc] initWithCString:ip];

/* Build our socket context; this ties an instance of self to the socket */
CFSocketContext CTX = { 0, self, NULL, NULL, NULL };

/* Create the server socket as a TCP IPv4 socket and set a callback */
/* for calls to the socket's lower-level connect() function */  
TCPClient = CFSocketCreate(NULL, PF_INET, SOCK_STREAM, IPPROTO_TCP, kCFSocketDataCallBack, (CFSocketCallBack)ConnectCallBack, &CTX);

if (TCPClient == NULL)
  return;

/* Set the port and address we want to listen on */
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_len = sizeof(addr);
addr.sin_family = AF_INET;
addr.sin_port = htons(PORT);
addr.sin_addr.s_addr = inet_addr([ipAddress UTF8String]);

CFDataRef connectAddr = CFDataCreate(NULL, (unsigned char *)&addr, sizeof(addr));
CFSocketConnectToAddress(TCPClient, connectAddr, -1);
CFRunLoopSourceRef sourceRef = CFSocketCreateRunLoopSource(kCFAllocatorDefault, TCPClient, 0);
CFRunLoopAddSource(CFRunLoopGetCurrent(), sourceRef, kCFRunLoopCommonModes);
CFRelease(sourceRef);
CFRunLoopRun();

这就是我发送数据的方式,它基本上是一个字节数组

/* The native socket, used for various operations */
// TCPClient is a CFSocketRef member variable
CFSocketNativeHandle sock = CFSocketGetNative(TCPClient);

Byte byteData[3];
byteData[0] = 0;
byteData[1] = 4;
byteData[2] = 0;

send(sock, byteData, strlen(byteData)+1, 0);

最后,正如您可能已经注意到的,当我创建服务器时socket,我注册了一个kCFSocketDataCallBack类型的回调,这是代码。

void ConnectCallBack(CFSocketRef socket, CFSocketCallBackType type, CFDataRef address, const void *data, void *info)
{
    // SocketsViewController is the class that contains all the methods
    SocketsViewController *obj = (SocketsViewController*)info;

    UInt8 *unsignedData = (UInt8 *) CFDataGetBytePtr(data);

    char *value = (char*)unsignedData;
    NSString *text = [[NSString alloc]initWithCString:value length:strlen(value)];
    [obj writeToTextView:text];
    [text release]; 
}

实际上,这个回调是在我的代码中调用的,问题是我不知道如何获取Windows客户端发送给我的数据,我期望收到一个字节数组,但我不知道我如何从数据参数中获取这些字节。

如果有人可以帮助我找到一种方法来做到这一点,或者也许我指出另一种在客户端应用程序中从服务器获取数据的方法,我将非常感激。

谢谢。

I'm working in a project for the iPad, it is a small program and I need it to communicate with another software that runs on windows and act like a server; so the application that I'm creating for the iPad will be the client.

I'm using CFNetwork to do sockets communication, this is the way I'm establishing the connection:

char ip[] = "192.168.0.244";
NSString *ipAddress = [[NSString alloc] initWithCString:ip];

/* Build our socket context; this ties an instance of self to the socket */
CFSocketContext CTX = { 0, self, NULL, NULL, NULL };

/* Create the server socket as a TCP IPv4 socket and set a callback */
/* for calls to the socket's lower-level connect() function */  
TCPClient = CFSocketCreate(NULL, PF_INET, SOCK_STREAM, IPPROTO_TCP, kCFSocketDataCallBack, (CFSocketCallBack)ConnectCallBack, &CTX);

if (TCPClient == NULL)
  return;

/* Set the port and address we want to listen on */
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_len = sizeof(addr);
addr.sin_family = AF_INET;
addr.sin_port = htons(PORT);
addr.sin_addr.s_addr = inet_addr([ipAddress UTF8String]);

CFDataRef connectAddr = CFDataCreate(NULL, (unsigned char *)&addr, sizeof(addr));
CFSocketConnectToAddress(TCPClient, connectAddr, -1);
CFRunLoopSourceRef sourceRef = CFSocketCreateRunLoopSource(kCFAllocatorDefault, TCPClient, 0);
CFRunLoopAddSource(CFRunLoopGetCurrent(), sourceRef, kCFRunLoopCommonModes);
CFRelease(sourceRef);
CFRunLoopRun();

And this is the way I sent the data, which basically is a byte array

/* The native socket, used for various operations */
// TCPClient is a CFSocketRef member variable
CFSocketNativeHandle sock = CFSocketGetNative(TCPClient);

Byte byteData[3];
byteData[0] = 0;
byteData[1] = 4;
byteData[2] = 0;

send(sock, byteData, strlen(byteData)+1, 0);

Finally, as you may have noticed, when I create the server socket, I registered a callback for the kCFSocketDataCallBack type, this is the code.

void ConnectCallBack(CFSocketRef socket, CFSocketCallBackType type, CFDataRef address, const void *data, void *info)
{
    // SocketsViewController is the class that contains all the methods
    SocketsViewController *obj = (SocketsViewController*)info;

    UInt8 *unsignedData = (UInt8 *) CFDataGetBytePtr(data);

    char *value = (char*)unsignedData;
    NSString *text = [[NSString alloc]initWithCString:value length:strlen(value)];
    [obj writeToTextView:text];
    [text release]; 
}

Actually, this callback is being invoked in my code, the problem is that I don't know how can I get the data that the windows client sent me, I'm expecting to receive an array of bytes, but I don't know how can I get those bytes from the data param.

If anyone can help me to find a way to do this, or maybe me point me to another way to get the data from the server in my client application I would really appreciate it.

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

柳若烟 2024-09-12 22:48:29

在您的回调中,data 参数确实是 kCFSocketDataCallBack 回调类型的 CFDataRef 值。

CFDataRef dataRef = (CFDataRef) data;
Byte *array = new Byte[CFDataGetLength(dataRef)]; // Or use a fixed length
CFDataGetBytes(dataRef, CFRangeMake(0, CFDataGetLength(theData)), array);

然后array将包含字节数组。

In your callback, the data parameter is indeed a CFDataRef value for the kCFSocketDataCallBack callback type.

CFDataRef dataRef = (CFDataRef) data;
Byte *array = new Byte[CFDataGetLength(dataRef)]; // Or use a fixed length
CFDataGetBytes(dataRef, CFRangeMake(0, CFDataGetLength(theData)), array);

The array will then contains the array of byte.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文