• 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: Implementing a TCP port listener in Cocoa
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Implementing a TCP port listener in Cocoa


  • Subject: Re: Implementing a TCP port listener in Cocoa
  • From: Jakob Olesen <email@hidden>
  • Date: Wed, 28 Jun 2006 21:16:32 +0200


On 28/06/2006, at 16.06, Rick Hoge wrote:


I would like to implement an internet service from within a Cocoa application such that when a remote client requests a connection on a certain port the connection and subsequent service will be handled by the Cocoa application.


I want to do this using Cocoa Foundation classes if possible, but it's not really clear from the documentation how to set this up. Most of the documentation is geared towards Distributed Objects (DO) and not provision of a TCP port service in the classic Unix sense.

I think you need to use Core Foundation for a listening socket. CFSocket lets you create a socket that listens for incoming connections in a run loop. You get a callback for each connection. Check out http://developer.apple.com/samplecode/CFLocalServer/ index.html It is for UNIX domain sockets, but you can do the same for INET sockets.


Once you get a connection, you are passed a bsd-style file descriptor in the accept callback. Pass that to CFStreamCreatePairWithSocket() to get a CFReadStreamRef+CFWriteStreamRef pair. These are toll-free bridged to NSInputStream and NSOutputStream.


The code below is a bit messy - it is part of a Ruby wrapper for CFSocket. Apple's sample code is probably better.


static void
accept_callback(CFSocketRef s, CFSocketCallBackType callbackType, CFDataRef address, const void *data, void *info)
{
if (callbackType!=kCFSocketAcceptCallBack)
return;
CFSocketNativeHandle fd = *(CFSocketNativeHandle*)data;
// pass fd to CFStreamCreatePairWithSocket...
}


// ServerSocket.new(:host, port)
static VALUE
socket_initialize(int argc, VALUE *argv, VALUE slf)
{
    VALUE ahost, aport;
    rb_scan_args(argc, argv, "02", &ahost, &aport);

Socket *s = DATA_PTR(slf);
struct addrinfo hint;
memset(&hint, 0, sizeof(hint));
hint.ai_family = PF_UNSPEC;
hint.ai_socktype = SOCK_STREAM;
hint.ai_protocol = IPPROTO_TCP;
hint.ai_flags = AI_PASSIVE | AI_CANONNAME;
const char *hostname = NIL_P(ahost) ? 0 : StringValuePtr(ahost);
const char *servname = NIL_P(aport) ? 0 : RSTRING (rb_obj_as_string(aport))->ptr;
struct addrinfo *res = 0;
if (getaddrinfo(hostname, servname, &hint, &res))
rb_sys_fail("getaddrinfo");
if (!res)
rb_raise(rb_eIOError, "getaddrinfo(%s,%s) failed", hostname, servname);


CFSocketContext ctx = { 0, (void*)slf, cf_ruby_retain, cf_ruby_release, cf_ruby_copy_description };
s->sock = CFSocketCreate(kCFAllocatorDefault, res->ai_family, res->ai_socktype, res->ai_protocol, kCFSocketAcceptCallBack, accept_callback, &ctx);
if (!s->sock) {
freeaddrinfo(res);
rb_sys_fail("couldn't create socket");
}


CFDataRef addr = CFDataCreate(kCFAllocatorDefault, (UInt8*)res- >ai_addr, res->ai_addrlen);
//NSLog(@"getaddrinfo(%s,%s) -> %s %@", hostname, servname, res- >ai_canonname, addr);
freeaddrinfo(res);


int yes = 1;
setsockopt(CFSocketGetNative(s->sock), SOL_SOCKET, SO_REUSEADDR, (void *)&yes, sizeof(yes));


    // now bind
    CFSocketError err = CFSocketSetAddress(s->sock, addr);
    CFRelease(addr);
    if (err!=kCFSocketSuccess) {
        rb_sys_fail("couldn't bind socket");
    }
    return slf;
}

static VALUE
m_accept(VALUE slf)
{
// NSLog(@"accept slf=%p", slf);
Socket *s = DATA_PTR(slf);
s->block = rb_block_proc();
CFRunLoopSourceRef rls = CFSocketCreateRunLoopSource (kCFAllocatorDefault, s->sock, 0);
CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopCommonModes);
CFRelease(rls);
return Qnil;
}


_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden


  • Follow-Ups:
    • Re: Implementing a TCP port listener in Cocoa
      • From: Andrew Bowman <email@hidden>
References: 
 >Implementing a TCP port listener in Cocoa (From: Rick Hoge <email@hidden>)

  • Prev by Date: Re: Bind to element in dictionary in array
  • Next by Date: Find Mouse Location Inside CustomView
  • Previous by thread: Implementing a TCP port listener in Cocoa
  • Next by thread: Re: Implementing a TCP port listener in Cocoa
  • Index(es):
    • Date
    • Thread