X-Git-Url: http://git.ithinksw.org/ITFoundation.git/blobdiff_plain/5fadb328bb7952174fcb7a6bb867c9c11f801df9..b64cdf3e84e76273251024a99bbe275ed1eeae4b:/ITInetServerSocket.m diff --git a/ITInetServerSocket.m b/ITInetServerSocket.m index f4b9720..61791f8 100755 --- a/ITInetServerSocket.m +++ b/ITInetServerSocket.m @@ -9,6 +9,7 @@ #import "ITInetServerSocket.h" #import "ITInetSocket.h" #import +#import #import #import #import @@ -17,8 +18,7 @@ #import /* Too bad Objective-C doesn't have class variables... */ -static NSMutableDictionary *servsockets; -static NSTimer *timer; +static NSMutableSet *servsockets; @interface ITInetServerSocket(Private) +(void)registerSocket:(ITInetServerSocket*)sock; @@ -28,17 +28,17 @@ static NSTimer *timer; -(void)stopConnection; -(void)setupRendezvousAdvertising; -(void)stopRendezvousAdvertising; -+(void)setupTimer; -+(void)stopTimer; -+(void)globalTimerFunc:(NSTimer*)timer; --(BOOL)timerFunc; +-(void)setupThread; +-(void)stopThread; +-(void)newClient:(int)cfd; +-(void)socketAcceptLoop:(id)data; @end @implementation ITInetServerSocket + (void)initialize { - servsockets = [[NSMutableDictionary alloc] init]; - [self setupTimer]; + servsockets = [[NSMutableSet alloc] init]; + //[self setupTimer]; } - (id)init @@ -50,7 +50,9 @@ static NSTimer *timer; clients = [[NSMutableSet alloc] init]; service = nil; port = 0; + dieflag = 0; rndType = rndName = nil; + timer = nil; } return self; } @@ -64,7 +66,9 @@ static NSTimer *timer; clients = [[NSMutableSet alloc] init]; service = nil; port = 0; + dieflag = 0; rndType = rndName = nil; + timer = nil; } return self; } @@ -78,7 +82,7 @@ static NSTimer *timer; [rndType release]; } -- (BOOL)registerSocket +- (BOOL)start { if (!rndName || !rndType || !port) return NO; [ITInetServerSocket registerSocket:self]; @@ -133,31 +137,21 @@ static NSTimer *timer; +(void)registerSocket:(ITInetServerSocket*)sock { [sock setupConnection]; - [servsockets setObject:sock forKey:[NSString stringWithFormat:@"%lu",[sock port]]]; + [servsockets addObject:sock]; } +(void)unregisterSocket:(ITInetServerSocket*)sock { [sock stopConnection]; - [servsockets removeObjectForKey:[NSString stringWithFormat:@"%lu",[sock port]]]; + [servsockets removeObject:sock]; } -(short)lookupPortForServiceType:(NSString*)name { const char *_name = [name cString]; - struct addrinfo hints,*res; + struct addrinfo *res; short p; - - hints.ai_flags = AI_PASSIVE; - hints.ai_family = PF_INET; - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = IPPROTO_TCP; - hints.ai_addrlen = 0; - hints.ai_canonname = NULL; - hints.ai_addr = NULL; - hints.ai_next = NULL; - - getaddrinfo(NULL,_name,&hints,&res); + getaddrinfo(NULL,_name,NULL,&res); p = ntohs(((struct sockaddr_in *)res->ai_addr)->sin_port); freeaddrinfo(res); return p; @@ -165,16 +159,19 @@ static NSTimer *timer; -(void)setupConnection { - struct sockaddr_in sa; - - sockfd = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); - sa.sin_addr.s_addr = INADDR_ANY; - sa.sin_family = AF_INET; - sa.sin_port = htons(port); - bind(sockfd,(struct sockaddr *)&sa,sizeof(sa)); + struct addrinfo hints, *ai; + hints.ai_flags = AI_PASSIVE; + hints.ai_family = PF_INET6; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + hints.ai_addrlen = 0; + hints.ai_canonname = hints.ai_addr = hints.ai_next = NULL; + getaddrinfo(NULL,[[[NSNumber numberWithShort:port] stringValue] cString],&hints,&ai); + bind(sockfd,ai->ai_addr,ai->ai_addrlen); listen(sockfd, SOMAXCONN); - fcntl(sockfd,F_SETFL,O_NONBLOCK); + freeaddrinfo(ai); [self setupRendezvousAdvertising]; + [self setupThread]; } - (void)stopConnection @@ -199,49 +196,40 @@ static NSTimer *timer; service = nil; } -+ (void)setupTimer +- (void)setupThread { - if (!timer) timer = [NSTimer timerWithTimeInterval:0 target:self selector:@selector(globalTimerFunc:) userInfo:nil repeats:YES]; - [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode]; + NSPort *p1 = [NSPort port], *p2 = [NSPort port]; + NSConnection *dcon = [[NSConnection alloc] initWithReceivePort:p1 sendPort:p2]; + NSArray *par = [NSArray arrayWithObjects:p2,p1,nil]; + [dcon setRootObject:self]; + [NSThread detachNewThreadSelector:@selector(socketAcceptLoop:) toTarget:self withObject:par]; } -+ (void)stopTimer +- (void)stopThread { - [timer invalidate]; - [timer release]; - timer = nil; + dieflag = 1; } -+ (void)globalTimerFunc:(NSTimer*)timer +- (void)newClient:(int)cfd { - NSEnumerator *enume = [servsockets objectEnumerator]; - id obj; - - while (obj = [enume nextObject]) - { - [obj timerFunc]; - } + ITInetSocket *csocket = [[ITInetSocket alloc] initWithFD:cfd delegate:delegate]; + [clients addObject:csocket]; } -- (BOOL)timerFunc +- (void)socketAcceptLoop:(id)data { - if (sockfd != -1) + NSAutoreleasePool *ap = [[NSAutoreleasePool alloc] init]; + NSArray *par = data; + NSConnection *dcon = [[NSConnection alloc] initWithReceivePort:[par objectAtIndex:0] sendPort:[par objectAtIndex:1]]; + NSProxy *dp = [dcon rootProxy]; + while ((sockfd != -1) && !dieflag) { - struct sockaddr_in csa; - int csalen; signed int cfd; - cfd = accept(sockfd,(struct sockaddr*)&csa,&csalen); - if (cfd == -1) { - if (errno == EWOULDBLOCK) return NO; - else {perror("Too bad I haven't implemented error checking yet");} - } - else { - ITInetSocket *csocket = [[[ITInetSocket alloc] initWithFD:cfd delegate:self] autorelease]; - [clients addObject:csocket]; - [delegate newClientJoined:csocket]; - return YES; - } + cfd = accept(sockfd,NULL,NULL); + [(id)dp newClient:cfd]; } - return NO; + dieflag = 0; + [dcon release]; + [ap release]; } @end \ No newline at end of file