• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Datagram Socket Reading?
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Datagram Socket Reading?


  • Subject: Re: Datagram Socket Reading?
  • From: Douglas Davidson <email@hidden>
  • Date: Fri, 17 May 2002 13:42:39 -0700

On Thursday, May 16, 2002, at 06:55 PM, Douglas Davidson wrote:

No, you don't need that extra thread. You can use CFSocket for this. CFSocket is a CF type intended to allow sockets of more or less arbitrary type to serve as run loop sources. Note that CFSocket is not intended as a complete wrapper around the BSD sockets APIs; you still deal with a socket as usual, but you can be notified in your run loop e.g. when data arrives. There was a session at the recent WWDC that discussed this, among other issues. I'll see if I can put together some sample code for the UDP case.

There's another apple mailing list, email@hidden, where we've been discussing CFSocket. I posted to that list a small sample that I had presented at the recent WWDC session, showing minimally the use of CFSocket with TCP sockets. That's fairly easily adaptable to UDP.

Douglas Davidson

Here's the original sample. This gives a trivial http response to any request. The example is a bit abbreviated so as to fit on the slides, but it shows some of the basic ideas. Compiles with cc -framework CoreFoundation.

#import <CoreFoundation/CoreFoundation.h>
#include <sys/socket.h>
#include <netinet/in.h>

void receiveData(CFSocketRef child, CFSocketCallBackType type, CFDataRef address, const void *data, void *info) {
static char helloWorld[] = "HTTP/1.0 200 OK\r\n\r\nhello, world\r\n";
CFDataRef response = CFDataCreate(NULL, helloWorld, strlen(helloWorld));
CFSocketSendData(child, NULL, response, 0.0);
CFRelease(response);
CFSocketInvalidate(child);
CFRelease(child);
}

void acceptConnection(CFSocketRef socket, CFSocketCallBackType type, CFDataRef address, const void *data, void *info) {
CFSocketRef child = CFSocketCreateWithNative(NULL, *(CFSocketNativeHandle *)data, kCFSocketDataCallBack, receiveData, NULL);
CFRunLoopSourceRef childSource = CFSocketCreateRunLoopSource(NULL, child, 0);
CFRunLoopRef loop = CFRunLoopGetCurrent();
CFRunLoopAddSource(loop, childSource, kCFRunLoopDefaultMode);
CFRelease(childSource);
}

int main (int argc, const char *argv[]) {
struct sockaddr_in a = {0, AF_INET, 1234, 0};
CFDataRef d = CFDataCreate(NULL, (UInt8 *)&a, sizeof(struct sockaddr_in));
CFSocketSignature signature = {PF_INET, SOCK_STREAM, IPPROTO_TCP, d};
CFSocketRef socket = CFSocketCreateWithSocketSignature(NULL, &signature, kCFSocketAcceptCallBack, acceptConnection, NULL);
CFRunLoopSourceRef source = CFSocketCreateRunLoopSource(NULL, socket, 0);
CFRunLoopRef loop = CFRunLoopGetCurrent();
CFRunLoopAddSource(loop, source, kCFRunLoopDefaultMode);
CFRunLoopRun();
}

Here's a UDP example, this time an echo server:

#import <CoreFoundation/CoreFoundation.h>
#include <sys/socket.h>
#include <netinet/in.h>

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

int main (int argc, const char *argv[]) {
struct sockaddr_in a = {0, AF_INET, 1234, 0};
CFDataRef d1 = CFDataCreate(NULL, (UInt8 *)&a, sizeof(struct sockaddr_in));
CFSocketSignature signature = {PF_INET, SOCK_DGRAM, IPPROTO_UDP, d};
CFSocketRef socket = CFSocketCreateWithSocketSignature(NULL, &signature, kCFSocketDataCallBack, receiveData, NULL);
CFRunLoopSourceRef source = CFSocketCreateRunLoopSource(NULL, socket, 0);
CFRunLoopRef loop = CFRunLoopGetCurrent();
CFRunLoopAddSource(loop, source, kCFRunLoopDefaultMode);
CFRunLoopRun();
}

Now, these two examples both use kCFSocketDataCallBack; this causes CFSocket to not only notify you of data coming in, but also to read the data and present it to you. This makes for compact examples, but there are a number of situations where you will want to use kCFSocketReadCallBack instead, which causes CFSocket simply to notify you when data is available, and expect you to do the read yourself.

These examples also use CFSocketSendData(), which is a small convenience API for writing, which again is useful for producing compact examples. You may also wish to do the write part yourself; the primary purpose of CFSocket is simply to provide notifications in the run loop for various socket events, not to wrap other socket functionality like reading and writing.
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.
References: 
 >Re: Datagram Socket Reading? (From: Douglas Davidson <email@hidden>)

  • Prev by Date: NSTextField overwrites itself
  • Next by Date: Re: OT: PB keyboard navigation
  • Previous by thread: Re: Datagram Socket Reading?
  • Next by thread: AppleShareClient and link errors
  • Index(es):
    • Date
    • Thread