Similar questions have been asked, but problems seem to be very code specific, so hopefully this is OK.
I am trying to write an iOS application which listens for UDP broadcasts and acts on the data. More advanced implementations seem to suggest using background threads and raw sockets to implement this kind of feature, but I thought as a first attempt I would use CFSocket to keep things simple. I've studied the UDPEcho example from Apple, but have hit a wall.
I add the CFSocket to the RunLoop, but my callback never gets called. As is usu开发者_运维问答al with this type of code, this is pretty difficult to debug. I've used a lot of the error checking suggested in UDPEcho, and everything seems to get setup correctly. Here is the code:
I have an object called DataListener which manages the connections. This is in DataListener init (with error checking removed:
int sock;
int err;
CFRunLoopSourceRef rls;
const CFSocketContext context = { 0, self, NULL, NULL, NULL };
sock = socket(AF_INET, SOCK_DGRAM, 0);
# Setup address struct and bind to socket for broadcast
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_len = sizeof(addr);
addr.sin_family = AF_INET;
addr.sin_port = 51234;
addr.sin_addr.s_addr = INADDR_ANY;
err = bind(sock, (const struct sockaddr *) &addr, sizeof(addr));
# Set flags to non-blocking
int flags;
flags = fcntl(sock,F_GETFL);
err = fcntl(sock, F_SETFL, flags | O_NONBLOCK);
# CFSocket is created, stored in the object
self->_cfSocket = CFSocketCreateWithNative(NULL,sock,kCFSocketReadCallBack,
SocketReadCallback, &context);
sock = -1;
# CFSocket is added to the Main RunLoop
rls = CFSocketCreateRunLoopSource(NULL,self->_cfSocket,0);
CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode);
CFRelease(rls);
This function is meant to get the C callback (This function doesn't get called as expected):
static void SocketReadCallback(CFSocketRef s, CFSocketCallBackType type, CFDataRef address, const void *data, void *info){
DataListener* obj;
obj = (DataListener*) info;
NSLog(@"Got callback in C");
[obj readData];
}
The DataListener readData function is an Obj-C function which then handles the data.
Is there something wrong in my setup code? Is there a way to verify that the CFSocket is being put on the RunLoop correctly?
Thank you for any tips or suggestions for reading materials. I realize that in the future I should probably use a thread, but for this example I would like to figure out how to do this with CFSocket.
Update: Never did figure out what was wrong here. Moved on to asyncsocket: http://code.google.com/p/cocoaasyncsocket/ and life is good.
kCFSocketReadCallBack change to kCFSocketDataCallBack
Try to replace CFRunLoopGetCurrent() to CFRunLoopGetMain()
精彩评论