X-Git-Url: http://git.ithinksw.org/ITFoundation.git/blobdiff_plain/4740388716dc49958b8fab291e44ea26f2bc1578..2f6f5b098085f36298e23e690cf27b61b4e2ec36:/ITInetServerSocket.m diff --git a/ITInetServerSocket.m b/ITInetServerSocket.m new file mode 100755 index 0000000..dcc8805 --- /dev/null +++ b/ITInetServerSocket.m @@ -0,0 +1,151 @@ +// +// ITInetServerSocket.m +// ITFoundation +// +// Created by Alexander Strange on Thu Feb 13 2003. +// Copyright (c) 2003 __MyCompanyName__. All rights reserved. +// + +#import "ITInetServerSocket.h" +#import "ITInetSocket.h" +#import +#import +#import +#import +#import +#import + +@interface ITInetServerSocket(Private) +-(void)setupConnectionWithServiceName:(NSString*)name; +-(void)setupConnectionWithPortNumber:(NSNumber*)port; +-(void)setupRendezvousAdvertising:(NSString*)name; +-(void)setupTimer; +-(void)timerFunc:(NSTimer*)timer; +@end + +@implementation ITInetServerSocket +- (id)init +{ + if (self = [super init]) + { + sockfd = 0; + delegate = clients = nil; + } + return self; +} + +- (id)initWithServiceName:(NSString*)name delegate:(id)d +{ + if (self = [super init]) + { + delegate = [d retain]; + clients = [[NSMutableSet alloc] init]; + [self setupConnectionWithServiceName:name]; + } + return self; +} + +- (id)initWithPort:(NSNumber*)port rendezvousName:(NSString*)name delegate:(id)d +{ + if (self = [super init]) + { + delegate = [d retain]; + clients = [[NSMutableSet alloc] init]; + [self setupConnectionWithPortNumber:port]; + } + return self; +} + +- (void)dealloc +{ + [service stop]; + [service release]; + [clients release]; + [delegate release]; + shutdown(sockfd,2); +} + +- (int)sockfd +{ + return sockfd; +} + +- (NSSet*)clients +{ + return clients; +} + +- (id)delegate +{ + return delegate; +} +@end + +@implementation ITInetServerSocket(Private) +-(void)setupConnectionWithServiceName:(NSString*)name +{ + const char *_name = [name cString]; + struct addrinfo hints,*res; + + 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); + sockfd = socket(res->ai_family, res->ai_socktype,res->ai_protocol); + bind(sockfd, res->ai_addr, res->ai_addrlen); + listen(sockfd, SOMAXCONN); + fcntl(sockfd,F_SETFL,O_NONBLOCK); + freeaddrinfo(res); +} + +-(void)setupConnectionWithPortNumber:(NSNumber*)port +{ + short _port = [port shortValue]; + 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)); + listen(sockfd, SOMAXCONN); + fcntl(sockfd,F_SETFL,O_NONBLOCK); +} + +- (void)setupRendezvousAdvertising:(NSString*)name port:(NSNumber*)port +{ + service = [[NSNetService alloc] initWithDomain:@"" type:[NSString stringWithFormat:@"_%@._tcp.",name] port:htons([port shortValue])]; + [service publish]; +} + +- (void)setupTimer +{ + NSTimer *timer = [NSTimer timerWithTimeInterval:0 target:self selector:@selector(timerFunc:) userInfo:nil repeats:YES]; + [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode]; +} + +- (void)timerFunc:(NSTimer*)timer +{ + struct sockaddr_in csa; + int csalen; + signed int cfd; + (void) timer; + cfd = accept(sockfd,(struct sockaddr*)&csa,&csalen); + if (cfd == -1) { + if (errno == EWOULDBLOCK) return; + 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]; + + } +} +@end \ No newline at end of file