From: Sven-S. P. <ssp...@ea...> - 2009-07-30 11:08:07
|
I noticed an NSNetService advertised on my network. It is of type _nssocketport._tcp. and seems to be advertised by BibDesk in addition to its _bdsk._tcp. one by the command [[NSSocketPortNameServer sharedInstance] registerPort:receivePort name:sharingName] in line 599 of BDSKSharingServer. Is it intentional that two services are advertised via Bonjour? Sven -- Sven-S. Porst . http://earthlingsoft.net/ssp . AIM: cv47al Pass as best inventor! |
From: Christiaan H. <cmh...@gm...> - 2009-07-30 12:21:27
|
On Jul 30, 2009, at 1:07 PM, Sven-S. Porst wrote: > I noticed an NSNetService advertised on my network. It is of type > _nssocketport._tcp. and seems to be advertised by BibDesk in addition > to its _bdsk._tcp. one by the command > > [[NSSocketPortNameServer sharedInstance] registerPort:receivePort > name:sharingName] > > in line 599 of BDSKSharingServer. > > Is it intentional that two services are advertised via Bonjour? > > Sven > > -- > Sven-S. Porst . http://earthlingsoft.net/ssp . AIM: cv47al > Pass as best inventor! Yes, one to advertise bonjour and one for the actual connection to a individual clients. Christiaan |
From: Sven-S. P. <ssp...@ea...> - 2009-07-30 12:55:33
|
> Yes, one to advertise bonjour and one for the actual connection to a > individual clients. I'm not sure I understand this: Typically an application just advertises a single service, no matter how many ports it needs to open. Sven -- Sven-S. Porst . http://earthlingsoft.net/ssp . AIM: cv47al Pass as best inventor! |
From: Christiaan H. <cmh...@gm...> - 2009-07-30 13:17:53
|
On Jul 30, 2009, at 2:55 PM, Sven-S. Porst wrote: >> Yes, one to advertise bonjour and one for the actual connection to a >> individual clients. > > > I'm not sure I understand this: Typically an application just > advertises a single service, no matter how many ports it needs to > open. > > Sven I'm not sure myself. What do you use to see these services? And do you see it when you turn of sharing? Christiaan |
From: Sven-S. P. <ssp...@ea...> - 2009-07-30 13:45:09
|
> I'm not sure myself. What do you use to see these services? There are plenty of tools for that, like iStumber or RendezCon. If you're happy with the command line, you can also use the dns-sd command. dns-sd -B _bdsk will give you all BibDesk shared libraries, and dns-sd -B _nssocketport will show the NSSSocketPorts. > And do you see it when you turn of sharing? No, when I turn off BibDesk sharing, the NSSocketPort vanishes. That's how I figured out that it's BiBDesk's to begin with. Best Sven -- Sven-S. Porst . http://earthlingsoft.net/ssp . AIM: cv47al Pass as best inventor! |
From: Christiaan H. <cmh...@gm...> - 2009-07-30 13:42:05
|
On Jul 30, 2009, at 3:17 PM, Christiaan Hofman wrote: > > On Jul 30, 2009, at 2:55 PM, Sven-S. Porst wrote: > >>> Yes, one to advertise bonjour and one for the actual connection to a >>> individual clients. >> >> >> I'm not sure I understand this: Typically an application just >> advertises a single service, no matter how many ports it needs to >> open. >> >> Sven > > I'm not sure myself. What do you use to see these services? And do > you see it when you turn of sharing? > > Christiaan > I think I see it better now. I think the _nssocketport._tcp you see is the NSSocketPort registered by the NSSocketPortNameService by the line you mentioned (NSSocketPortNameService underneath also advertises using bonjour). The _bdsk,_tcp is the NSNetService created on line 286 in -newNetServiceWithSharingName:. The first one is the named socket port that's used for clients to connect back to (using DO through NSConnection), and is created in a background thread. The second one advertises the service and the sharing name, and is searched for by NSNetseviceBrowser. Perhaps it would be possible to use a single service with a single port (in the background thread), but I'm not sure if that works with DO (I've certainly never seen sample code for that). I know too little about ports to know for sure if the port used by the netservice can be used for DO. The only thing I know for communicating over this port is directly passing data over the input/output streams, but that's too low-level. Christiaan |
From: Sven-S. P. <ssp...@ea...> - 2009-07-30 14:14:30
|
> Perhaps it would be possible to use a single service with a single > port (in the background thread), but I'm not sure if that works with > DO (I've certainly never seen sample code for that). I know too little > about ports to know for sure if the port used by the netservice can be > used for DO. Rest assured that I'm likely to know far less than you do about these things. I just want to make clear that my point weren't the open ports anyway, but the fact that they are advertised via Bonjour. Does that additional port have to advertised in this way so other applications can discover it independently (that'd seem unlikely to me as it's unclear how the service would be identified from the Bonjour entry without any description beyond that it's a generic NSSocketPort). Sven -- Sven-S. Porst . http://earthlingsoft.net/ssp . AIM: cv47al Pass as best inventor! |
From: Christiaan H. <cmh...@gm...> - 2009-07-30 14:38:10
|
On Jul 30, 2009, at 4:14 PM, Sven-S. Porst wrote: >> Perhaps it would be possible to use a single service with a single >> port (in the background thread), but I'm not sure if that works with >> DO (I've certainly never seen sample code for that). I know too >> little >> about ports to know for sure if the port used by the netservice can >> be >> used for DO. > > Rest assured that I'm likely to know far less than you do about these > things. > > I just want to make clear that my point weren't the open ports anyway, > but the fact that they are advertised via Bonjour. Does that > additional port have to advertised in this way so other applications > can discover it independently (that'd seem unlikely to me as it's > unclear how the service would be identified from the Bonjour entry > without any description beyond that it's a generic NSSocketPort). > > > Sven The second port has to be advertised for the client to connect back to it. Others should not independently connect to it, but that's the way NSSocketPortNameServer works. As it's generic, that shouldn't happen. Christiaan |
From: Adam R. M. <ama...@ma...> - 2009-07-30 14:38:57
Attachments:
smime.p7s
|
On Jul 30, 2009, at 7:14 AM, Sven-S. Porst wrote: >> Perhaps it would be possible to use a single service with a single >> port (in the background thread), but I'm not sure if that works with >> DO (I've certainly never seen sample code for that). I know too >> little >> about ports to know for sure if the port used by the netservice can >> be >> used for DO. I tried that a couple of times and couldn't get it to work. I don't know enough about BSD sockets to do anything more. > I just want to make clear that my point weren't the open ports anyway, > but the fact that they are advertised via Bonjour. Does that > additional port have to advertised in this way so other applications > can discover it independently (that'd seem unlikely to me as it's > unclear how the service would be identified from the Bonjour entry > without any description beyond that it's a generic NSSocketPort). It's not for discovery. It's internal DO machinery from NSSocketPortNameServer, as Christiaan said, and it lets you connect over an NSPort by knowing only the service name and hostname. Your alternative would be vending it over a hard-coded TCP port number, according to the documentation. -- adam |
From: Christiaan H. <cmh...@gm...> - 2009-07-30 18:48:18
|
On Jul 30, 2009, at 4:38 PM, Adam R. Maxwell wrote: > > On Jul 30, 2009, at 7:14 AM, Sven-S. Porst wrote: > >>> Perhaps it would be possible to use a single service with a single >>> port (in the background thread), but I'm not sure if that works with >>> DO (I've certainly never seen sample code for that). I know too >>> little >>> about ports to know for sure if the port used by the netservice >>> can be >>> used for DO. > > I tried that a couple of times and couldn't get it to work. I don't > know enough about BSD sockets to do anything more. > Did you ever try something like this <http://www.cocoadev.com/index.pl?DistributedObjectsAndBonjour >? Christiaan >> I just want to make clear that my point weren't the open ports >> anyway, >> but the fact that they are advertised via Bonjour. Does that >> additional port have to advertised in this way so other applications >> can discover it independently (that'd seem unlikely to me as it's >> unclear how the service would be identified from the Bonjour entry >> without any description beyond that it's a generic NSSocketPort). > > It's not for discovery. It's internal DO machinery from > NSSocketPortNameServer, as Christiaan said, and it lets you connect > over an NSPort by knowing only the service name and hostname. Your > alternative would be vending it over a hard-coded TCP port number, > according to the documentation. > > -- adam |
From: Maxwell, A. R <ada...@pn...> - 2009-07-30 19:13:45
|
On 07/30/09 11:48, "Christiaan Hofman" <cmh...@gm...> wrote: > > On Jul 30, 2009, at 4:38 PM, Adam R. Maxwell wrote: > >> >> On Jul 30, 2009, at 7:14 AM, Sven-S. Porst wrote: >> >>>> Perhaps it would be possible to use a single service with a single >>>> port (in the background thread), but I'm not sure if that works with >>>> DO (I've certainly never seen sample code for that). I know too >>>> little >>>> about ports to know for sure if the port used by the netservice >>>> can be >>>> used for DO. >> >> I tried that a couple of times and couldn't get it to work. I don't >> know enough about BSD sockets to do anything more. >> > > Did you ever try something like this > <http://www.cocoadev.com/index.pl?DistributedObjectsAndBonjour Something similar, I think, and I disabled my firewall. I think whichever one uses the port first keeps the other from using it. DO has so much magic involved that it's hard to know what went wrong. What bothers me is that calling write() on the same socket from different threads or objects seems wrong, so I'm not sure they can be the same. >> ? > > Christiaan > >>> I just want to make clear that my point weren't the open ports >>> anyway, >>> but the fact that they are advertised via Bonjour. Does that >>> additional port have to advertised in this way so other applications >>> can discover it independently (that'd seem unlikely to me as it's >>> unclear how the service would be identified from the Bonjour entry >>> without any description beyond that it's a generic NSSocketPort). >> >> It's not for discovery. It's internal DO machinery from >> NSSocketPortNameServer, as Christiaan said, and it lets you connect >> over an NSPort by knowing only the service name and hostname. Your >> alternative would be vending it over a hard-coded TCP port number, >> according to the documentation. >> >> -- adam > > > ------------------------------------------------------------------------------ > Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day > trial. Simplify your report design, integration and deployment - and focus on > what you do best, core application coding. Discover what's new with > Crystal Reports now. http://p.sf.net/sfu/bobj-july > _______________________________________________ > Bibdesk-develop mailing list > Bib...@li... > https://lists.sourceforge.net/lists/listinfo/bibdesk-develop |
From: Christiaan H. <cmh...@gm...> - 2009-07-30 20:28:51
|
On Jul 30, 2009, at 9:13 PM, Maxwell, Adam R wrote: > > > > On 07/30/09 11:48, "Christiaan Hofman" <cmh...@gm...> wrote: > >> >> On Jul 30, 2009, at 4:38 PM, Adam R. Maxwell wrote: >> >>> >>> On Jul 30, 2009, at 7:14 AM, Sven-S. Porst wrote: >>> >>>>> Perhaps it would be possible to use a single service with a single >>>>> port (in the background thread), but I'm not sure if that works >>>>> with >>>>> DO (I've certainly never seen sample code for that). I know too >>>>> little >>>>> about ports to know for sure if the port used by the netservice >>>>> can be >>>>> used for DO. >>> >>> I tried that a couple of times and couldn't get it to work. I don't >>> know enough about BSD sockets to do anything more. >>> >> >> Did you ever try something like this >> <http://www.cocoadev.com/index.pl?DistributedObjectsAndBonjour > > Something similar, I think, and I disabled my firewall. I think > whichever > one uses the port first keeps the other from using it. DO has so > much magic > involved that it's hard to know what went wrong. What bothers me is > that > calling write() on the same socket from different threads or objects > seems > wrong, so I'm not sure they can be the same. > I think for any single port setup to work the netservice and the connection should better work on the same thread, in this case the background thread. I wish Apple had a sample of DO and Bonjour, but all available sample code seems to be either one or the other. Christiaan > >>> ? >> >> Christiaan >> >>>> I just want to make clear that my point weren't the open ports >>>> anyway, >>>> but the fact that they are advertised via Bonjour. Does that >>>> additional port have to advertised in this way so other >>>> applications >>>> can discover it independently (that'd seem unlikely to me as it's >>>> unclear how the service would be identified from the Bonjour entry >>>> without any description beyond that it's a generic NSSocketPort). >>> >>> It's not for discovery. It's internal DO machinery from >>> NSSocketPortNameServer, as Christiaan said, and it lets you connect >>> over an NSPort by knowing only the service name and hostname. Your >>> alternative would be vending it over a hard-coded TCP port number, >>> according to the documentation. >>> >>> -- adam >> >> >> ------------------------------------------------------------------------------ >> Let Crystal Reports handle the reporting - Free Crystal Reports >> 2008 30-Day >> trial. Simplify your report design, integration and deployment - >> and focus on >> what you do best, core application coding. Discover what's new with >> Crystal Reports now. http://p.sf.net/sfu/bobj-july >> _______________________________________________ >> Bibdesk-develop mailing list >> Bib...@li... >> https://lists.sourceforge.net/lists/listinfo/bibdesk-develop > > > ------------------------------------------------------------------------------ > Let Crystal Reports handle the reporting - Free Crystal Reports 2008 > 30-Day > trial. Simplify your report design, integration and deployment - and > focus on > what you do best, core application coding. Discover what's new with > Crystal Reports now. http://p.sf.net/sfu/bobj-july > _______________________________________________ > Bibdesk-develop mailing list > Bib...@li... > https://lists.sourceforge.net/lists/listinfo/bibdesk-develop |
From: Maxwell, A. R <ada...@pn...> - 2009-07-30 21:01:43
|
On 07/30/09 13:28, "Christiaan Hofman" <cmh...@gm...> wrote: > On Jul 30, 2009, at 9:13 PM, Maxwell, Adam R wrote: > >> DO has so >> much magic >> involved that it's hard to know what went wrong. What bothers me is >> that >> calling write() on the same socket from different threads or objects >> seems >> wrong, so I'm not sure they can be the same. >> > > I think for any single port setup to work the netservice and the > connection should better work on the same thread, in this case the > background thread. Yeah, I think that might work, but you have no control over what thread the bonjour advertisement runs on. When you call publish, NSNetService could run its own thread, as well as use a runloop source (strange as that would be). It was just easier to let NSNetService and NSSocketPort choose their own ports and be done with it. I know people have asked for a fixed port, but Leopard's firewall takes care of that in a much nicer way. > I wish Apple had a sample of DO and Bonjour, but all available sample > code seems to be either one or the other. I've never seen any sample code that uses both, so I modified the PictureSharing sample to use DO. I've still never seen sample code other than my own that tears down a DO connection without leaking mach ports; in fact, I filed a doc request on that over 2 years ago and it's still open. My guess is that Apple wishes DO would just go away, given their lack of attention to it. |
From: Maxwell, A. R <ada...@pn...> - 2009-07-31 23:01:24
|
I tried using an NSSocketPort to get a port for the NSNetService and DO, just out of curiosity. This code creates a service that shows up in the browse list, until I added the final assertion. So receivePort is still valid, but the NSSocketPortNameServer returns a port that's not valid (or maybe nil...I didn't check). So even if there is a way to make it work by eliminating NSSocketPortNameServer, I'd hate to say whether it worked by accident or design, DO being what it is :). #import <Foundation/Foundation.h> #import <sys/socket.h> #include <netinet/in.h> #include <unistd.h> int main (int argc, char const *argv[]) { NSAutoreleasePool *pool = [NSAutoreleasePool new]; NSString *sharingName = @"DO test name"; NSPort *receivePort = [NSSocketPort port]; BOOL didRegister = [receivePort isValid] && [[NSSocketPortNameServer sharedInstance] registerPort:receivePort name:sharingName]; NSCParameterAssert(didRegister); int fd = [(NSSocketPort *)receivePort socket]; NSCParameterAssert(fd >= 0); const struct sockaddr_in *saddr = [[(NSSocketPort *)receivePort address] bytes]; uint16_t port = ntohs(saddr->sin_port); NSLog(@"port = %d", port); NSNetService *service = [[NSNetService alloc] initWithDomain:@"" type:@"_bdsk._tcp." name:sharingName port:port]; NSMutableDictionary *dictionary = [NSMutableDictionary dictionaryWithCapacity:4]; [dictionary setObject:@"0" forKey:@"txtvers"]; [dictionary setObject:@"NO" forKey:@"authenticate"]; [dictionary setObject:@"dummy" forKey:@"ident"]; [service setTXTRecordData:[NSNetService dataFromTXTRecordDictionary:dictionary]]; [service publishWithOptions:0]; NSCParameterAssert([receivePort isValid]); NSCParameterAssert([[[NSSocketPortNameServer sharedInstance] portForName:sharingName] isValid]); [[NSRunLoop currentRunLoop] run]; [pool drain]; return 0; } |
From: Christiaan H. <cmh...@gm...> - 2009-07-31 23:15:45
|
I don't think you can use NSSocketPortNameServer for this. The problem is that NSSocketPortNameServer only looks for type _nsnetservice._tcp, while the NSNetService registers the port for type _bdsk._tcp. I think to connect back somehow you need to look up the port yourself, perhaps using the address of the NSNetService. Something like getting the port and family from the address and getting the NSSocketPort from there, like in the second sample on <http://www.cocoadev.com/index.pl?DistributedObjectsAndBonjour >. Christiaan On Aug 1, 2009, at 1:01 AM, Maxwell, Adam R wrote: > I tried using an NSSocketPort to get a port for the NSNetService and > DO, > just out of curiosity. This code creates a service that shows up in > the > browse list, until I added the final assertion. So receivePort is > still > valid, but the NSSocketPortNameServer returns a port that's not > valid (or > maybe nil...I didn't check). > > So even if there is a way to make it work by eliminating > NSSocketPortNameServer, I'd hate to say whether it worked by > accident or > design, DO being what it is :). > > #import <Foundation/Foundation.h> > #import <sys/socket.h> > #include <netinet/in.h> > #include <unistd.h> > > int main (int argc, char const *argv[]) > { > NSAutoreleasePool *pool = [NSAutoreleasePool new]; > > NSString *sharingName = @"DO test name"; > NSPort *receivePort = [NSSocketPort port]; > > BOOL didRegister = [receivePort isValid] && > [[NSSocketPortNameServer > sharedInstance] registerPort:receivePort name:sharingName]; > NSCParameterAssert(didRegister); > > int fd = [(NSSocketPort *)receivePort socket]; > NSCParameterAssert(fd >= 0); > > const struct sockaddr_in *saddr = [[(NSSocketPort *)receivePort > address] > bytes]; > > uint16_t port = ntohs(saddr->sin_port); > NSLog(@"port = %d", port); > > NSNetService *service = [[NSNetService alloc] initWithDomain:@"" > type:@"_bdsk._tcp." name:sharingName port:port]; > > NSMutableDictionary *dictionary = [NSMutableDictionary > dictionaryWithCapacity:4]; > [dictionary setObject:@"0" forKey:@"txtvers"]; > [dictionary setObject:@"NO" forKey:@"authenticate"]; > [dictionary setObject:@"dummy" forKey:@"ident"]; > > [service setTXTRecordData:[NSNetService > dataFromTXTRecordDictionary:dictionary]]; > [service publishWithOptions:0]; > > NSCParameterAssert([receivePort isValid]); > NSCParameterAssert([[[NSSocketPortNameServer sharedInstance] > portForName:sharingName] isValid]); > > [[NSRunLoop currentRunLoop] run]; > > [pool drain]; > return 0; > } > > > ------------------------------------------------------------------------------ > Let Crystal Reports handle the reporting - Free Crystal Reports 2008 > 30-Day > trial. Simplify your report design, integration and deployment - and > focus on > what you do best, core application coding. Discover what's new with > Crystal Reports now. http://p.sf.net/sfu/bobj-july > _______________________________________________ > Bibdesk-develop mailing list > Bib...@li... > https://lists.sourceforge.net/lists/listinfo/bibdesk-develop |
From: Christiaan H. <cmh...@gm...> - 2009-08-02 12:38:01
|
I tried that but this also fails, slightly differently though. One point seems to be that -isValid does not seem to be correct. When I check this in BibDesk, it also returns NO, but we know it works. BTW, the port in your code is not nil. When I try my proposal, the it seems to work, including an NSConnection. However when I try to send a DO message I get a log (not an exception) saying *** NSDistantObject initWithCoder: 0x2 not given away for conn 0x113140 Christiaan On Sat, Aug 1, 2009 at 1:15 AM, Christiaan Hofman <cmh...@gm...>wrote: > I don't think you can use NSSocketPortNameServer for this. The problem is > that NSSocketPortNameServer only looks for type _nsnetservice._tcp, while > the NSNetService registers the port for type _bdsk._tcp. I think to connect > back somehow you need to look up the port yourself, perhaps using the > address of the NSNetService. Something like getting the port and family from > the address and getting the NSSocketPort from there, like in the second > sample on <http://www.cocoadev.com/index.pl?DistributedObjectsAndBonjour>. > > Christiaan > > > On Aug 1, 2009, at 1:01 AM, Maxwell, Adam R wrote: > > I tried using an NSSocketPort to get a port for the NSNetService and DO, >> just out of curiosity. This code creates a service that shows up in the >> browse list, until I added the final assertion. So receivePort is still >> valid, but the NSSocketPortNameServer returns a port that's not valid (or >> maybe nil...I didn't check). >> >> So even if there is a way to make it work by eliminating >> NSSocketPortNameServer, I'd hate to say whether it worked by accident or >> design, DO being what it is :). >> >> #import <Foundation/Foundation.h> >> #import <sys/socket.h> >> #include <netinet/in.h> >> #include <unistd.h> >> >> int main (int argc, char const *argv[]) >> { >> NSAutoreleasePool *pool = [NSAutoreleasePool new]; >> >> NSString *sharingName = @"DO test name"; >> NSPort *receivePort = [NSSocketPort port]; >> >> BOOL didRegister = [receivePort isValid] && [[NSSocketPortNameServer >> sharedInstance] registerPort:receivePort name:sharingName]; >> NSCParameterAssert(didRegister); >> >> int fd = [(NSSocketPort *)receivePort socket]; >> NSCParameterAssert(fd >= 0); >> >> const struct sockaddr_in *saddr = [[(NSSocketPort *)receivePort address] >> bytes]; >> >> uint16_t port = ntohs(saddr->sin_port); >> NSLog(@"port = %d", port); >> >> NSNetService *service = [[NSNetService alloc] initWithDomain:@"" >> type:@"_bdsk._tcp." name:sharingName port:port]; >> >> NSMutableDictionary *dictionary = [NSMutableDictionary >> dictionaryWithCapacity:4]; >> [dictionary setObject:@"0" forKey:@"txtvers"]; >> [dictionary setObject:@"NO" forKey:@"authenticate"]; >> [dictionary setObject:@"dummy" forKey:@"ident"]; >> >> [service setTXTRecordData:[NSNetService >> dataFromTXTRecordDictionary:dictionary]]; >> [service publishWithOptions:0]; >> >> NSCParameterAssert([receivePort isValid]); >> NSCParameterAssert([[[NSSocketPortNameServer sharedInstance] >> portForName:sharingName] isValid]); >> >> [[NSRunLoop currentRunLoop] run]; >> >> [pool drain]; >> return 0; >> } >> >> >> >> ------------------------------------------------------------------------------ >> Let Crystal Reports handle the reporting - Free Crystal Reports 2008 >> 30-Day >> trial. Simplify your report design, integration and deployment - and focus >> on >> what you do best, core application coding. Discover what's new with >> Crystal Reports now. http://p.sf.net/sfu/bobj-july >> _______________________________________________ >> Bibdesk-develop mailing list >> Bib...@li... >> https://lists.sourceforge.net/lists/listinfo/bibdesk-develop >> > > |
From: Christiaan H. <cmh...@gm...> - 2009-08-02 16:39:50
|
On Aug 2, 2009, at 2:37 PM, Christiaan Hofman wrote: > I tried that but this also fails, slightly differently though. > > One point seems to be that -isValid does not seem to be correct. > When I check this in BibDesk, it also returns NO, but we know it > works. BTW, the port in your code is not nil. > > When I try my proposal, the it seems to work, including an > NSConnection. However when I try to send a DO message I get a log > (not an exception) saying > > *** NSDistantObject initWithCoder: 0x2 not given away for conn > 0x113140 > > Christiaan > I have been able to get it to work with a single port. In fact in two ways. One is to both name and retrieve the port using NSSocketPortNameServer, this will still give two bonjour services to turn up in browsers. However, I can also get it to work /without/ NSSocketPortNameServer, so only one service shows up. Of course this won't be compatible with BibDesk's current code, so I don't think we should be using that, but it may be just nice to know. The crucial difference with what I tried before is that the sendPort is created using -initRemoteWithTCPPort:host:, getting the port from one of the netServices addresses. The code is below (slightly redacted to remove some unnecessary stuff). Christiaan #import <Foundation/Foundation.h> #import <sys/socket.h> #include <netinet/in.h> #include <unistd.h> @interface Server : NSObject { NSNetService *service; NSConnection *connection; } - (oneway void)connectClient:(byref id)client; @end @interface Browser : NSObject { NSNetServiceBrowser *browser; NSMutableArray *services; NSMutableArray *clients; } @end @interface Client : NSObject { NSNetService *service; NSConnection *connection; } - (id)initWithService:(NSNetService *)aNetService; @end static BOOL _getFamilyAndPort(NSData *addressData, uint16_t *family, uint16_t *port) { struct sockaddr *address = (struct sockaddr *)[addressData bytes]; if (address->sa_family == AF_INET) { NSLog(@"family is AF_INET"); if (family) *family = AF_INET; if (port) *port = ntohs(((struct sockaddr_in *)address)- >sin_port); return YES; } else if(address->sa_family == AF_INET6) { NSLog(@"family is AF_INET6"); if (family) *family = AF_INET6; if (port) *port = ntohs(((struct sockaddr_in6 *)address)- >sin6_port); return YES; } else { NSLog(@"unknown family"); return NO; } } @implementation Server - (id)init { if (self = [super init]) { NSString *sharingName = @"DO test name"; NSPort *receivePort = [NSSocketPort port]; connection = [[NSConnection alloc] initWithReceivePort:receivePort sendPort:nil]; [connection setRootObject:self]; uint16_t port = 0; _getFamilyAndPort([(NSSocketPort *)receivePort address], NULL, &port); NSLog(@"port = %d", port); service = [[NSNetService alloc] initWithDomain:@"" type:@"_mytest._tcp." name:sharingName port:port]; [service publishWithOptions:0]; } return self; } - (oneway void)connectClient:(byref id)client { NSLog(@"connectClient: %@", client); } @end @implementation Browser - (id)init { if (self = [super init]) { services = [NSMutableArray new]; clients = [NSMutableArray new; browser = [NSNetServiceBrowser new]; [browser setDelegate:self]; [browser searchForServicesOfType:@"_mytest._tcp." inDomain:@""]; } return self; } - (void)netServiceBrowser:(NSNetServiceBrowser *)aNetServiceBrowser didFindService:(NSNetService *)aNetService moreComing:(BOOL)moreComing { NSLog(@"found service %@", aNetService); [services addObject:aNetService]; [aNetService setDelegate:self]; [aNetService resolveWithTimeout:5.0]; } - (void)netServiceDidResolveAddress:(NSNetService *)aNetService { NSLog(@"Did resolve %@", aNetService); [aNetService setDelegate:nil]; Client *client = [[[Client alloc] initWithService:aNetService] autorelease]; [clients addObject:client]; [services removeObject:aNetService]; } - (void)netService:(NSNetService *)aNetService didNotResolve:(NSDictionary *)errorDict { NSLog(@"Did not resolve %@", aNetService); [aNetService setDelegate:nil]; [services removeObject:aNetService]; } @end @implementation Client - (id)initWithService:(NSNetService *)aNetService { if (self = [super init]) { service = [aNetService retain]; NSData *addressData = [[service addresses] lastObject]; uint16_t family = 0, port = 0; _getFamilyAndPort(addressData, &family, &port); NSLog(@"port is %d", port); // this works only for AF_INET, but a remote connection only gets AF_INET6 //NSPort *sendPort = [[[NSSocketPort alloc] initRemoteWithProtocolFamily:family socketType:SOCK_STREAM protocol:IPPROTO_TCP address:addressData] autorelease]; NSPort *sendPort = [[[NSSocketPort alloc] initRemoteWithTCPPort:port host:[service hostName]] autorelease]; // isValid here always returns NO, even when things work NSLog(@"%d %@", [sendPort isValid], sendPort); connection = [[NSConnection alloc] initWithReceivePort:nil sendPort:sendPort]; [connection setRequestTimeout:60]; @try { [(Server *)[connection rootProxy] connectClient:self]; } @catch(id e) { NSLog(@"Caught exception %@", e); } } return self; } @end int main (int argc, char const *argv[]) { NSAutoreleasePool *pool = [NSAutoreleasePool new]; [Server new]; [Browser new]; [[NSRunLoop currentRunLoop] run]; [pool drain]; return 0; } |
From: Sven-S. P. <ssp...@ea...> - 2009-07-30 18:13:55
|
> It's not for discovery. It's internal DO machinery from > NSSocketPortNameServer, as Christiaan said, and it lets you connect > over an NSPort by knowing only the service name and hostname. Your > alternative would be vending it over a hard-coded TCP port number, > according to the documentation. I'm not sure I understand this (Bonjour _is_ for discovery, yet this use of it isn't?) but it seems that this is a quirk of Apple's implementation rather than a BibDesk issue. It also seems like BibDesk is the only application I have that uses Distributed Objects at all, as I haven't seen those NSSocketPort Bonjour advertisements otherwise. Sven -- Sven-S. Porst . http://earthlingsoft.net/ssp . AIM: cv47al Pass as best inventor! |
From: Christiaan H. <cmh...@gm...> - 2009-07-30 18:43:11
|
On Jul 30, 2009, at 8:13 PM, Sven-S. Porst wrote: >> It's not for discovery. It's internal DO machinery from >> NSSocketPortNameServer, as Christiaan said, and it lets you connect >> over an NSPort by knowing only the service name and hostname. Your >> alternative would be vending it over a hard-coded TCP port number, >> according to the documentation. > > > I'm not sure I understand this (Bonjour _is_ for discovery, yet this > use of it isn't?) That's not really correct, though which part is not correct depends on what you mean with "discovery". BD names the second port by a given name, so the client can find it back by that name (and standard type). I would call that discovery, and it certainly is done using Bonjour. > but it seems that this is a quirk of Apple's > implementation rather than a BibDesk issue. > It also seems like BibDesk is the only application I have that uses > Distributed Objects at all, as I haven't seen those NSSocketPort > Bonjour advertisements otherwise. > > Sven We're not saying that you need two ports to have bonjour with DO, we say that we don't know how to do it with one ;-) I do think it should be possible to have it with only one port. One of the problems is that NSSocketPortNameServer (which is used for the second port) only seems to work with the standard type, and also NSSocketPort is somewhat limited (AFAIK it can't handle just any BSD socket port). However, the browsable netservice uses a special registered type (_bdsk). Christiaan |