1

I've just begun developing with networking on the iPhone. I need to develop a simple app for talking to a Wifi router. The thing is, the wifi box communicates over UDP. I've dug around quite a bit, but all the sample code I've seen so far, have examples for TCP comms, except for one; the UDPEcho example.

So, my questions are: 1. How do I know if a device on a WiFi network can be connected on WiFi? 2. For communicating on UDP, can I simply create a socket, and send data using the CFSocketSendData method to some address?

It seemds like the UDPEcho example, first creates a host, then resolves it, then gets an address, and after binding to a socket sends some data. I want a simplistic raw implementation for simply sending a packet and receiving a packet in response.

Any links or references will be helpful. Even more helpful, will be some basic steps for a raw implementation. In simple terms, can I do the following: 1. Create a socket using CFSocketCreate, specifying a callback when data is available for reading. 2. Send data on the socket using CFSocketSend, specifying the address I would like to send.

EDIT: I created a class SocketTest and then called connect: followed by sendData. Here's the code:

#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

However, I still wasn't able to send data to my server. I am running a simple C-coded listening server on another machine to test my code.

Also, tried the AsyncUDPSocket library with much success. However, wanted to know the intricacies of the thing. The AsyncUDPSocket library gets and resolces IPv4 or IPv6 addresses. In my code for SocketTest, I am simply specifyinhg an IPv4 address.

So, my question refined is, why does this piece of code not work? Is there something very small, but very crucial that I am missing? Would appreciate any help on the same.

Thanks.

Angelo
  • 173
  • 2
  • 4
  • 13

0 Answers0