IOS4 — Отправка данных с использованием сокета UDP

#objective-c #c #networking #ios4

#objective-c #c #сеть #ios4

Вопрос:

Я только начал разработку с использованием сети на iPhone. Мне нужно разработать простое приложение для связи с маршрутизатором Wifi. Дело в том, что wifi box обменивается данными через UDP. Я немного покопался, но во всех примерах кода, которые я видел до сих пор, есть примеры для TCP-связи, за исключением одного; пример UDPEcho.

Итак, мои вопросы: 1. Как мне узнать, может ли устройство в сети Wi-Fi быть подключено по Wi-Fi? 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(amp;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 *)amp;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
                                    amp;signature,             //Signature we created above
                                    kCFSocketDataCallBack,  //Callback that will read data into a CFData object
                                    dataReadyToRead,            //The method that will be called as callback
                                    amp;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
                                amp;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)),
                    amp;receivedData
                );

    //Show data received in label.

}

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

    static char helloworld[] = "rnHello 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-адрес.

Итак, мой уточненный вопрос заключается в том, почему этот фрагмент кода не работает? Есть ли что-то очень маленькое, но очень важное, чего мне не хватает? Был бы признателен за любую помощь по тому же вопросу.

Спасибо.