IOS4 - 使用UDP套接字发送数据

时间:2011-05-02 11:57:26

标签: objective-c c networking ios4

我刚刚开始在iPhone上开发网络。我需要开发一个简单的应用程序来与Wifi路由器交谈。问题是,wifi盒通过UDP进行通信。我已经挖了很多,但到目前为止我看过的所有示例代码都有TCP通信的例子,除了一个; UDPEcho示例。

所以,我的问题是: 1.我如何知道WiFi网络上的设备是否可以通过WiFi连接? 2.对于UDP上的通信,我可以简单地创建一个套接字,并使用CFSocketSendData方法将数据发送到某个地址吗?

看起来像UDPEcho示例,首先创建一个主机,然后解析它,然后获取一个地址,并在绑定到套接字后发送一些数据。我想要一个简单的原始实现,只需发送数据包并接收数据包作为响应。

任何链接或参考都会有所帮助。更有帮助的是,原始实现的一些基本步骤。 简单来说,我可以执行以下操作: 1.使用CFSocketCreate创建套接字,在数据可供读取时指定回调。 2.使用CFSocketSend在套接字上发送数据,指定我想发送的地址。

编辑:我创建了一个类SocketTest,然后调用connect:后跟sendData。这是代码:

#include "SocketTest.h"

@implementation SocketTest

- (BOOL)connectSocket{
    CFSocketRef appSocket;
    const CFSocketContext socketContext = { 0, self, NULL, NULL, NULL };
    CFRunLoopSourceRef socketRunLoopSourceRef;

    struct sockaddr_in deviceAddress;   

    /**
        We have to bind a machine address to the socket which we will create. For this,
        we need to store our address and port number into a structure of the type,
        struct_sockaddr_in (since, we will be using IPv4).
    */
    /**
        Part 1: Create address structure.
    */
    //Clear memory reserved for socket address.
    memset(&deviceAddress, 0, sizeof(deviceAddress));

    //Create our remote device address
    deviceAddress.sin_addr.s_addr = inet_addr("192.168.0.1"); //Convert string to suitable usage format and store as address.
    deviceAddress.sin_family = AF_INET;
    deviceAddress.sin_port = (u_short)9009;

    //Put the device address into a CFDataRef object.
    CFDataRef address = CFDataCreate(NULL, (UInt8 *)&deviceAddress, sizeof(struct sockaddr_in));

    //If there was a problem with previous call, return with error.
    if (NULL == address) {
        return 1;
    }

    /**
        Part 2: Create socket with a signature and add it to run loop.
    */
    //Create a socket signature that specifies the communication protocol and the connection address.
    const CFSocketSignature signature = {
                                    PF_INET,                //Protocol family IPv4
                                    SOCK_DGRAM,             //Datagram socket
                                    IPPROTO_UDP,            //Protocol is UDP
                                    address                 //CFDataRef object holding the contents of our remote address.
                                };

    //Create socket with the signature just created
    appSocket =  CFSocketCreateConnectedToSocketSignature(
                                    NULL,                   //Default memory allocator
                                    &signature,             //Signature we created above
                                    kCFSocketDataCallBack,  //Callback that will read data into a CFData object
                                    dataReadyToRead,            //The method that will be called as callback
                                    &socketContext,
                                    0.0
                                );  

    //Create socket
    /*
    appSocket = CFSocketCreate(
                                NULL,                   //Default memory allocator
                                PF_INET,                //Protocol Family IPv4
                                SOCK_DGRAM,             //Datagram socket (UDP)
                                IPPROTO_UDP,            //Protocol is UDP
                                kCFSocketDataCallBack,  //Flag to tell socket to call our callback when data is ready
                                dataReadyCallBack,      //The call back function that will be called
                                &socketContext          //The socket context
                            );
    */

    //Create run loop source, with our socket as the source
    socketRunLoopSourceRef = CFSocketCreateRunLoopSource(
                                NULL,                   //Default memory allocator
                                appSocket,              //Socket created
                                0                       //Highest priority source
                            );

    //Add to surrent run loop
    CFRunLoopAddSource(
                        CFRunLoopGetCurrent(),          //Add to current run loop
                        socketRunLoopSourceRef,         //Add this run loop source
                        kCFRunLoopDefaultMode           //The default mode of the run loop
                    );

    CFRelease(socketRunLoopSourceRef);

    //Return success
    return 0;

}

static void receiveData(CFSocketRef socket, CFSocketCallBackType type, CFDataRef address, const void *data, void *info) {
    //CFSocketSendData(socket, address, (CFDataRef)data, 0.0);

    CFDataRef buffer;
    UInt8 *receivedData;

    buffer = (CFDataRef)data;

    CFDataGetBytes(
                    buffer,
                    CFRangeMake(0,CFDataGetLength(theData)),
                    &receivedData
                );

    //Show data received in label.

}

BOOL sendData: (void *)data{
    CFSocketError socketErrors;

    static char helloworld[] = "\r\nHello world";

    CFDataRef _packet = CFDataCreate(NULL, (const UInt8 *)helloworld, strlen(helloworld));

    socketErrors = CFSocketSendData(appSocket, NULL, packet, 0.0);

    return;
}

@end

但是,我仍然无法将数据发送到我的服务器。我在另一台机器上运行一个简单的C编码监听服务器来测试我的代码。

此外,尝试了AsyncUDPSocket库并取得了很大成功。但是,想知道事情的复杂性。 AsyncUDPSocket库获取并解析IPv4或IPv6地址。在我的SocketTest代码中,我只是指定了一个IPv4地址。

所以,我提出的问题是,为什么这段代码不起作用?有什么东西很小,但是我错过了非常重要的东西吗?非常感谢任何帮助。

感谢。

0 个答案:

没有答案