Added -[TCPConnection initToNetService:] to make it easier to use with Bonjour. This allowed me to simplify BLIPEchoClient quite a lot.
1.1 --- a/BLIP/Demo/BLIPEchoClient.h Sun May 25 12:33:50 2008 -0700
1.2 +++ b/BLIP/Demo/BLIPEchoClient.h Sun May 25 13:43:03 2008 -0700
1.3 @@ -20,7 +20,7 @@
1.4
1.5 NSNetServiceBrowser * _serviceBrowser;
1.6 NSMutableArray * _serviceList;
1.7 - NSNetService *_resolvingService;
1.8 +
1.9 BLIPConnection *_connection;
1.10 }
1.11
2.1 --- a/BLIP/Demo/BLIPEchoClient.m Sun May 25 12:33:50 2008 -0700
2.2 +++ b/BLIP/Demo/BLIPEchoClient.m Sun May 25 13:43:03 2008 -0700
2.3 @@ -10,7 +10,6 @@
2.4
2.5 #import "BLIPEchoClient.h"
2.6 #import "BLIP.h"
2.7 -#import "IPAddress.h"
2.8 #import "Target.h"
2.9
2.10
2.11 @@ -28,24 +27,6 @@
2.12 }
2.13
2.14 #pragma mark -
2.15 -#pragma mark BLIPConnection support
2.16 -
2.17 -/* Opens a BLIP connection to the given address. */
2.18 -- (void)openConnection: (IPAddress*)address
2.19 -{
2.20 - _connection = [[BLIPConnection alloc] initToAddress: address];
2.21 - [_connection open];
2.22 -}
2.23 -
2.24 -/* Closes the currently open BLIP connection. */
2.25 -- (void)closeConnection
2.26 -{
2.27 - [_connection close];
2.28 - [_connection release];
2.29 - _connection = nil;
2.30 -}
2.31 -
2.32 -#pragma mark -
2.33 #pragma mark NSNetServiceBrowser delegate methods
2.34
2.35 // We broadcast the willChangeValueForKey: and didChangeValueForKey: for the NSTableView binding to work.
2.36 @@ -67,43 +48,24 @@
2.37 }
2.38
2.39 #pragma mark -
2.40 -#pragma mark NSNetService delegate methods
2.41 +#pragma mark BLIPConnection support
2.42
2.43 -/* Stop any current Bonjour address resolution */
2.44 -- (void)stopResolving
2.45 +/* Opens a BLIP connection to the given address. */
2.46 +- (void)openConnection: (NSNetService*)service
2.47 {
2.48 - if( _resolvingService ) {
2.49 - _resolvingService.delegate = nil;
2.50 - [_resolvingService stop];
2.51 - [_resolvingService release];
2.52 - _resolvingService = nil;
2.53 - }
2.54 -}
2.55 -
2.56 -/* Ask Bonjour to resolve (look up) the IP address of the given service. */
2.57 -- (void)startResolving: (NSNetService*)service
2.58 -{
2.59 - [self stopResolving];
2.60 - _resolvingService = [service retain];
2.61 - _resolvingService.delegate = self;
2.62 - [_resolvingService resolveWithTimeout: 5.0];
2.63 -
2.64 + _connection = [[BLIPConnection alloc] initToNetService: service];
2.65 + if( _connection )
2.66 + [_connection open];
2.67 + else
2.68 + NSBeep();
2.69 }
2.70
2.71 -/* NSNetService delegate method that will be called when address resolution finishes. */
2.72 -- (void)netServiceDidResolveAddress:(NSNetService *)sender
2.73 +/* Closes the currently open BLIP connection. */
2.74 +- (void)closeConnection
2.75 {
2.76 - if( sender == _resolvingService ) {
2.77 - // Get the first address, which is an NSData containing a struct sockaddr:
2.78 - NSArray *addresses = _resolvingService.addresses;
2.79 - if( addresses.count > 0 ) {
2.80 - NSData *addressData = [addresses objectAtIndex: 0];
2.81 - IPAddress *address = [[IPAddress alloc] initWithSockAddr: addressData.bytes];
2.82 - [self openConnection: address];
2.83 - [address release];
2.84 - }
2.85 - [self stopResolving];
2.86 - }
2.87 + [_connection close];
2.88 + [_connection release];
2.89 + _connection = nil;
2.90 }
2.91
2.92 #pragma mark -
2.93 @@ -114,17 +76,14 @@
2.94 int selectedRow = [table selectedRow];
2.95
2.96 [self closeConnection];
2.97 - [self stopResolving];
2.98 -
2.99 - if (-1 != selectedRow) {
2.100 - [self startResolving: [_serviceList objectAtIndex:selectedRow]];
2.101 - }
2.102 + if (-1 != selectedRow)
2.103 + [self openConnection: [_serviceList objectAtIndex:selectedRow]];
2.104 }
2.105
2.106 /* Send a BLIP request containing the string in the textfield */
2.107 - (IBAction)sendText:(id)sender
2.108 {
2.109 - BLIPRequest *r = [_connection requestWithBody: nil];
2.110 + BLIPRequest *r = [_connection request];
2.111 r.bodyString = [sender stringValue];
2.112 BLIPResponse *response = [r send];
2.113 response.onComplete = $target(self,gotResponse:);
3.1 --- a/MYNetwork.xcodeproj/project.pbxproj Sun May 25 12:33:50 2008 -0700
3.2 +++ b/MYNetwork.xcodeproj/project.pbxproj Sun May 25 13:43:03 2008 -0700
3.3 @@ -531,6 +531,7 @@
3.4 GCC_C_LANGUAGE_STANDARD = gnu99;
3.5 GCC_OPTIMIZATION_LEVEL = 0;
3.6 GCC_PREPROCESSOR_DEFINITIONS = DEBUG;
3.7 + GCC_TREAT_WARNINGS_AS_ERRORS = YES;
3.8 GCC_WARN_ABOUT_RETURN_TYPE = YES;
3.9 GCC_WARN_UNUSED_VARIABLE = YES;
3.10 ONLY_ACTIVE_ARCH = YES;
3.11 @@ -545,6 +546,7 @@
3.12 buildSettings = {
3.13 ARCHS = "$(ARCHS_STANDARD_32_BIT)";
3.14 GCC_C_LANGUAGE_STANDARD = gnu99;
3.15 + GCC_TREAT_WARNINGS_AS_ERRORS = YES;
3.16 GCC_WARN_ABOUT_RETURN_TYPE = YES;
3.17 GCC_WARN_UNUSED_VARIABLE = YES;
3.18 PREBINDING = NO;
4.1 --- a/TCP/TCPConnection.h Sun May 25 12:33:50 2008 -0700
4.2 +++ b/TCP/TCPConnection.h Sun May 25 13:43:03 2008 -0700
4.3 @@ -46,6 +46,10 @@
4.4 - (id) initToAddress: (IPAddress*)address
4.5 localPort: (UInt16)localPort;
4.6
4.7 +/** Initializes a TCPConnection to the given NSNetService's address and port.
4.8 + If the service's address cannot be resolved, nil is returned. */
4.9 +- (id) initToNetService: (NSNetService*)service;
4.10 +
4.11 /** Initializes a TCPConnection from an incoming TCP socket.
4.12 You don't usually need to call this; TCPListener does it automatically. */
4.13 - (id) initIncomingFromSocket: (CFSocketNativeHandle)socket listener: (TCPListener*)listener;
4.14 @@ -79,7 +83,7 @@
4.15 + (void) waitTillAllClosed;
4.16
4.17 /** The IP address of the other peer. */
4.18 -@property (readonly) IPAddress *address;
4.19 +@property (readonly,retain) IPAddress *address;
4.20
4.21 /** The TCPListener that created this incoming connection, or nil */
4.22 @property (readonly) TCPListener *server;
5.1 --- a/TCP/TCPConnection.m Sun May 25 12:33:50 2008 -0700
5.2 +++ b/TCP/TCPConnection.m Sun May 25 13:43:03 2008 -0700
5.3 @@ -19,6 +19,7 @@
5.4
5.5 @interface TCPConnection ()
5.6 @property TCPConnectionStatus status;
5.7 +@property (retain) IPAddress *address;
5.8 - (BOOL) _checkIfClosed;
5.9 - (void) _closed;
5.10 @end
5.11 @@ -40,7 +41,7 @@
5.12 {
5.13 self = [super init];
5.14 if (self != nil) {
5.15 - if( !address || !input || !output ) {
5.16 + if( !input || !output ) {
5.17 LogTo(TCP,@"Failed to create %@: addr=%@, in=%@, out=%@",
5.18 self.class,address,input,output);
5.19 [self release];
5.20 @@ -49,7 +50,7 @@
5.21 _address = [address copy];
5.22 _reader = [[[self readerClass] alloc] initWithConnection: self stream: input];
5.23 _writer = [[[self writerClass] alloc] initWithConnection: self stream: output];
5.24 - LogTo(TCP,@"%@ initialized",self);
5.25 + LogTo(TCP,@"%@ initialized, address=%@",self,address);
5.26 }
5.27 return self;
5.28 }
5.29 @@ -74,6 +75,22 @@
5.30 return [self initToAddress: address localPort: 0];
5.31 }
5.32
5.33 +- (id) initToNetService: (NSNetService*)service
5.34 +{
5.35 + IPAddress *address = nil;
5.36 + NSInputStream *input;
5.37 + NSOutputStream *output;
5.38 + if( [service getInputStream: &input outputStream: &output] ) {
5.39 + NSArray *addresses = service.addresses;
5.40 + if( addresses.count > 0 )
5.41 + address = [[[IPAddress alloc] initWithSockAddr: [[addresses objectAtIndex: 0] bytes]] autorelease];
5.42 + } else {
5.43 + input = nil;
5.44 + output = nil;
5.45 + }
5.46 + return [self _initWithAddress: address inputStream: input outputStream: output];
5.47 +}
5.48 +
5.49
5.50 - (id) initIncomingFromSocket: (CFSocketNativeHandle)socket
5.51 listener: (TCPListener*)listener
5.52 @@ -253,8 +270,10 @@
5.53
5.54 - (void) _streamOpened: (TCPStream*)stream
5.55 {
5.56 + if( ! _address )
5.57 + self.address = stream.peerAddress;
5.58 if( _status==kTCP_Opening && _reader.isOpen && _writer.isOpen ) {
5.59 - LogTo(TCP,@"%@ opened",self);
5.60 + LogTo(TCP,@"%@ opened; address=%@",self,_address);
5.61 self.status = kTCP_Open;
5.62 [self tellDelegate: @selector(connectionDidOpen:) withObject: nil];
5.63 }
6.1 --- a/TCP/TCPStream.h Sun May 25 12:33:50 2008 -0700
6.2 +++ b/TCP/TCPStream.h Sun May 25 13:43:03 2008 -0700
6.3 @@ -7,7 +7,7 @@
6.4 //
6.5
6.6 #import <Foundation/Foundation.h>
6.7 -@class TCPConnection, TCPWriter;
6.8 +@class TCPConnection, TCPWriter, IPAddress;
6.9
6.10
6.11 /** Abstract superclass for data streams, used by TCPConnection. */
6.12 @@ -20,6 +20,9 @@
6.13
6.14 - (id) initWithConnection: (TCPConnection*)conn stream: (NSStream*)stream;
6.15
6.16 +/** The IP address this stream is connected to. */
6.17 +@property (readonly) IPAddress *peerAddress;
6.18 +
6.19 /** The connection's security level as reported by the underlying CFStream. */
6.20 @property (readonly) NSString *securityLevel;
6.21
7.1 --- a/TCP/TCPStream.m Sun May 25 12:33:50 2008 -0700
7.2 +++ b/TCP/TCPStream.m Sun May 25 13:43:03 2008 -0700
7.3 @@ -8,6 +8,7 @@
7.4
7.5 #import "TCPStream.h"
7.6 #import "TCP_Internal.h"
7.7 +#import "IPAddress.h"
7.8
7.9 #import "Logging.h"
7.10 #import "Test.h"
7.11 @@ -46,11 +47,20 @@
7.12
7.13 - (id) propertyForKey: (CFStringRef)cfStreamProperty
7.14 {
7.15 - return nil; // abstract -- overridden by TCPReader and TCPWriter
7.16 + return [_stream propertyForKey: (NSString*)cfStreamProperty];
7.17 }
7.18
7.19 - (void) setProperty: (id)value forKey: (CFStringRef)cfStreamProperty
7.20 -{ // abstract -- overridden by TCPReader and TCPWriter
7.21 +{
7.22 + if( ! [_stream setProperty: value forKey: (NSString*)cfStreamProperty] )
7.23 + Warn(@"Failed to set property %@ on %@",cfStreamProperty,self);
7.24 +}
7.25 +
7.26 +
7.27 +- (IPAddress*) peerAddress
7.28 +{
7.29 + const CFSocketNativeHandle *socketPtr = [[self propertyForKey: kCFStreamPropertySocketNativeHandle] bytes];
7.30 + return socketPtr ?[IPAddress addressOfSocket: *socketPtr] :nil;
7.31 }
7.32
7.33
7.34 @@ -225,20 +235,6 @@
7.35 return _conn.writer;
7.36 }
7.37
7.38 -
7.39 -- (id) propertyForKey: (CFStringRef)cfStreamProperty
7.40 -{
7.41 - CFTypeRef value = CFReadStreamCopyProperty((CFReadStreamRef)_stream,cfStreamProperty);
7.42 - return [(id)CFMakeCollectable(value) autorelease];
7.43 -}
7.44 -
7.45 -- (void) setProperty: (id)value forKey: (CFStringRef)cfStreamProperty
7.46 -{
7.47 - if( ! CFReadStreamSetProperty((CFReadStreamRef)_stream,cfStreamProperty,(CFTypeRef)value) )
7.48 - Warn(@"%@ didn't accept property '%@'", self,cfStreamProperty);
7.49 -}
7.50 -
7.51 -
7.52 - (NSInteger) read: (void*)dst maxLength: (NSUInteger)maxLength
7.53 {
7.54 NSInteger bytesRead = [(NSInputStream*)_stream read:dst maxLength: maxLength];
8.1 --- a/TCP/TCPWriter.m Sun May 25 12:33:50 2008 -0700
8.2 +++ b/TCP/TCPWriter.m Sun May 25 13:43:03 2008 -0700
8.3 @@ -30,19 +30,6 @@
8.4 }
8.5
8.6
8.7 -- (id) propertyForKey: (CFStringRef)cfStreamProperty
8.8 -{
8.9 - CFTypeRef value = CFWriteStreamCopyProperty((CFWriteStreamRef)_stream,cfStreamProperty);
8.10 - return [(id)CFMakeCollectable(value) autorelease];
8.11 -}
8.12 -
8.13 -- (void) setProperty: (id)value forKey: (CFStringRef)cfStreamProperty
8.14 -{
8.15 - if( ! CFWriteStreamSetProperty((CFWriteStreamRef)_stream,cfStreamProperty,(CFTypeRef)value) )
8.16 - Warn(@"%@ didn't accept property '%@'", self,cfStreamProperty);
8.17 -}
8.18 -
8.19 -
8.20 - (BOOL) isBusy
8.21 {
8.22 return _currentData || _queue.count > 0;