From: Alexander Strange Date: Sun, 16 Mar 2003 19:57:20 +0000 (+0000) Subject: More socket work X-Git-Tag: v0.1~34 X-Git-Url: http://git.ithinksw.org/ITFoundation.git/commitdiff_plain/d0e2a23f6909335baea90af08491a5160026757b More socket work --- diff --git a/ITAppleEventCenter.m b/ITAppleEventCenter.m index 535154b..5f485e0 100755 --- a/ITAppleEventCenter.m +++ b/ITAppleEventCenter.m @@ -1,12 +1,6 @@ #import "ITAppleEventCenter.h" -Boolean MyAEIdleCallback ( - EventRecord * theEvent, - SInt32 * sleepTime, - RgnHandle * mouseRgn - ); - -Boolean MyAEIdleCallback ( +static Boolean MyAEIdleCallback ( EventRecord * theEvent, SInt32 * sleepTime, RgnHandle * mouseRgn diff --git a/ITByteStream.h b/ITByteStream.h index 3d726b1..eeb9c76 100755 --- a/ITByteStream.h +++ b/ITByteStream.h @@ -19,5 +19,6 @@ -(id) initWithStream:(ITByteStream*)stream; -(int) availableDataLength; -(NSData*) readDataOfLength:(int)length; +-(NSData*) readAllData; -(void) writeData:(in NSData*)data; @end diff --git a/ITByteStream.m b/ITByteStream.m index eff6eb7..4d34eb0 100755 --- a/ITByteStream.m +++ b/ITByteStream.m @@ -64,6 +64,16 @@ return ret; } +-(NSData*) readAllData +{ + NSData *ret; + [lock lock]; + ret = [data autorelease]; + data = [[NSMutableData alloc] init]; + [lock unlock]; + return ret; +} + -(void) writeData:(NSData*)_data { [lock lock]; diff --git a/ITInetSocket.h b/ITInetSocket.h index 2f25958..aaf55b9 100755 --- a/ITInetSocket.h +++ b/ITInetSocket.h @@ -70,7 +70,7 @@ typedef enum { * @discussion The delegate should check [sender readPipe] to get the data. * @param sender The socket that the messages came from. */ -- (void) dataRecieved:(ITInetSocket *)sender; +- (void) dataRecieved:(in ITInetSocket *)sender; /*! * @method errorOccured:during:onSocket: * @abstract Alerts the delegate of an error condition. @@ -79,14 +79,14 @@ typedef enum { * @param state What the socket was doing when the error occured. * @param sender The socket the error occured on. */ -- (void) errorOccured:(ITInetSocketError)err during:(ITInetSocketState)state onSocket:(ITInetSocket*)sender; +- (void) errorOccured:(ITInetSocketError)err during:(ITInetSocketState)state onSocket:(in ITInetSocket*)sender; /*! * @method finishedConnecting: * @abstract Alerts the delegate of a successful connection attempt. * @discussion The delegate should send whatever initial data is required for the protocol (nickname for IRC, etc.) * @param sender The socket that established the connection. */ -- (void) finishedConnecting:(ITInetSocket *)sender; +- (void) finishedConnecting:(in ITInetSocket *)sender; @end /*! @@ -96,19 +96,48 @@ typedef enum { */ @interface ITInetSocket : NSObject { @public + /*! + * @var sockfd + * @abstract KLWONZ + */ int sockfd; int port; - id delegate; + unsigned short bufs; + int dieflag; + int actionflag; + id delegate; struct addrinfo *ai, *ai_cur; ITByteStream *readPipe, *writePipe; ITInetSocketState state; NSArray *sarr; } -+(void)startAutoconnectingToService:(NSString*)type delegate:(id )d; --(id) initWithFD:(int)fd delegate:(id )d; --(id) initWithDelegate:(id )d; +/*! + * @method startAutoconnectingToService:delegate: + * @abstract Automatically creates sockets whenever a certain type of Rendezvous service appears. + * @discussion The auto-created sockets will send finishedConnecting: to the delegate. + * @param type The type of Rendezvous service to listen on. + * @param d The delegate that the sockets will belong to. + */ ++(void)startAutoconnectingToService:(NSString*)type delegate:(id )d; +/*! + * @method initWithFD:delegate: + * @abstract Wraps a socket around an existing socket descriptor. + * @discussion The socket will start listening on the descriptor as normal. + * @param fd The descriptor. + * @param d The delegate for the socket. + */ +-(id) initWithFD:(int)fd delegate:(id )d; +/*! + * @method initWithDelegate: + * @abstract Creates a new socket. + * @discussion The socket will not be connected to anything. + * @param d The delegate of the socket. + */ +-(id) initWithDelegate:(id )d; -(id )delegate; +-(unsigned short)bufferSize; +-(void)setBufferSize:(unsigned short)bufs; -(void) connectToHost:(NSString*)host onPort:(short)port; -(void) connectToHost:(NSString*)host onNamedPort:(NSString*)port; -(void) connectWithSockaddrArray:(NSArray*)arr; diff --git a/ITInetSocket.m b/ITInetSocket.m index 4e40628..7d3989b 100755 --- a/ITInetSocket.m +++ b/ITInetSocket.m @@ -10,7 +10,7 @@ #import "ITServiceBrowserDelegate.h" #import #import - +#import @interface ITInetSocket(Debugging) -(NSString*)dumpv6Addrinfo:(struct addrinfo *)_ai; @@ -18,10 +18,12 @@ @interface ITInetSocket(Private) -(void)doConnSetupWithHost:(NSString*)host namedPort:(NSString*)namedPort; +-(void)spinoffReadLoop; +-(void)socketReadLoop:(id)data; @end @implementation ITInetSocket -+(void)startAutoconnectingToService:(NSString*)type delegate:(id)d ++(void)startAutoconnectingToService:(NSString*)type delegate:(id )d { NSNetServiceBrowser *browse = [[NSNetServiceBrowser alloc] init]; ITServiceBrowserDelegate *bd = [[ITServiceBrowserDelegate alloc] initWithDelegate:d]; @@ -30,7 +32,7 @@ [browse searchForServicesOfType:[NSString stringWithFormat:@"._%@._tcp",type] inDomain:nil]; } --(id)initWithFD:(int)fd delegate:(id)d +-(id)initWithFD:(int)fd delegate:(id )d { if (self = [super init]) { @@ -42,21 +44,13 @@ readPipe = [[ITByteStream alloc] init]; ai = nil; sarr = nil; + bufs = 512; + actionflag = dieflag = 0; } return self; } --(void) dealloc -{ - shutdown(sockfd,2); - [delegate release]; - [writePipe release]; - [readPipe release]; - if (!sarr) freeaddrinfo(ai); - [sarr release]; -} - --(id)initWithDelegate:(id)d +-(id)initWithDelegate:(id )d { if (self = [super init]) { @@ -68,10 +62,23 @@ readPipe = [[ITByteStream alloc] init]; ai = nil; sarr = nil; + bufs = 512; + actionflag = dieflag = 0; } return self; } + +-(void) dealloc +{ + shutdown(sockfd,2); + [delegate release]; + [writePipe release]; + [readPipe release]; + if (!sarr) freeaddrinfo(ai); + [sarr release]; +} + -(void) connectToHost:(NSString*)host onPort:(short)thePort { if (state == ITInetSocketDisconnected) @@ -91,25 +98,50 @@ -(void) connectWithSockaddrArray:(NSArray*)arr { - NSEnumerator *e = [arr objectEnumerator]; - NSData *d; - struct addrinfo *a; - ai = malloc(sizeof(struct addrinfo)); - a = ai; - while (d = [e nextObject]) + if (state == ITInetSocketDisconnected) + { + NSEnumerator *e = [arr objectEnumerator]; + NSData *d; + struct addrinfo *a; + ai = malloc(sizeof(struct addrinfo)); + a = ai; + while (d = [e nextObject]) { - struct sockaddr *s = (struct sockaddr*)[d bytes]; - a->ai_family = s->sa_family; - a->ai_addr = s; - a->ai_next = malloc(sizeof(struct addrinfo)); - a = a->ai_next; + struct sockaddr *s = (struct sockaddr*)[d bytes]; + a->ai_family = s->sa_family; + a->ai_addr = s; + a->ai_next = malloc(sizeof(struct addrinfo)); + a = a->ai_next; + } } } +-(void)disconnect +{ +} + +-(void)retryConnection +{ +} + -(ITInetSocketState)state { return state; } +-(id )delegate +{ + return delegate; +} + +-(unsigned short)bufferSize +{ + return bufs; +} + +-(void)setBufferSize:(unsigned short)_bufs +{ + bufs = _bufs; +} @end @implementation ITInetSocket(Debugging) @@ -168,4 +200,49 @@ } NSLog([self dumpv6Addrinfo:ai]); } + +-(void)spinoffReadLoop +{ + NSPort *p1 = [NSPort port], *p2 = [NSPort port]; + NSConnection *dcon = [[NSConnection alloc] initWithReceivePort:p1 sendPort:p2]; + NSArray *par = [NSArray arrayWithObjects:p2,p1,nil]; + [dcon setRootObject:delegate]; + [NSThread detachNewThreadSelector:@selector(socketReadLoop:) toTarget:self withObject:par]; //spawn read thread +} + +-(void)socketReadLoop:(id)data +{ + NSAutoreleasePool *ap = [[NSAutoreleasePool alloc] init]; + NSConnection *dcon = [[NSConnection alloc] initWithReceivePort:[data objectAtIndex:0] sendPort:[data objectAtIndex:1]]; + NSProxy *dp = [dcon rootProxy]; + char *buf = malloc(bufs); + unsigned long readLen = 0; + +lstart: + do + { + NSData *d = [NSData alloc]; + readLen = recv(sockfd,buf,bufs,0); + [d initWithBytesNoCopy:buf length:readLen]; + [readPipe writeData:d]; + [d release]; + [dp dataRecieved:self]; + } + while (!actionflag); + actionflag = 0; + if (dieflag) + { + free(buf); + [dcon release]; + [ap release]; + dieflag = 0; + return; + } + + { + NSData *d = [writePipe readAllData]; + write(sockfd,[d bytes],[d length]); + goto lstart; + } +} @end \ No newline at end of file