objective c - Connecting to a server with NSNetService but failing- automatic socket disconnect? -
new simpler version of problem:
i'm trying connect , communicate bonjour device using objective-c client , i'm having trouble resolving service (server). tried more complicated example, found basic socket connection port/ip specified wasn't working.
i have barebones possible code using cocoaasyncsocket library:
asyncsocket *xxx = [[[asyncsocket alloc] initwithdelegate:self] autorelease]; nserror **err; [xxx connecttohost: @"localhost" onport: 5000 error: err]; nslog(@"err=%@",err);
and here's server i'm trying connect (python script):
# tcp server bonjour broadcast! import select import sys import pybonjour import socket time import sleep #name = sys.argv[1] #regtype = sys.argv[2] #port = int(sys.argv[3]) # bonjour service parameters name = "test" regtype = "_xxx._tcp." port = 5000 # tcp socket stuff server_socket = socket.socket(socket.af_inet, socket.sock_stream) server_socket.bind(("", port)) server_socket.listen(5) def register_callback(sdref, flags, errorcode, name, regtype, domain): if errorcode == pybonjour.kdnsserviceerr_noerror: print 'registered service:' print ' name =', name print ' regtype =', regtype print ' domain =', domain sdref = pybonjour.dnsserviceregister(name = name, regtype = regtype, port = port, callback = register_callback) # register bonjour service print "registering bonjour service" ready = select.select([sdref], [], []) print "ready=",ready if sdref in ready[0]: pybonjour.dnsserviceprocessresult(sdref) def configloop(): data = "entering configuration mode" client_socket.send (data) data = "1) network ssid: " client_socket.send (data) ssid = client_socket.recv(512) print "network ssid:",ssid data = "2) login: " client_socket.send (data) login = client_socket.recv(512) print "login:",login data = "3) password: " client_socket.send (data) passw = client_socket.recv(512) print "password:",passw data = "restarting server , attempting connect "+ssid client_socket.send (data) sleep(1) sys.exit(0) print "tcpserver waiting client on port",port try: while 1: client_socket, address = server_socket.accept() print "i got connection ", address data = "connection!" client_socket.send (data) while 1: data = client_socket.recv(512) if ( data == 'q' or data == 'q'): client_socket.close() break; elif (data == 'c' or data == 'config'): # enter configuration mode configloop(); else: print "recieved:" , data finally: sdref.close()
the server never sees incoming connection. on client side, error var has value or something- nothing i'd expect. please?
old (more complicated version, uses same server):
my debug output says service resolved... , socket disconnect after. meanwhile server sits there , hasn't seen incoming connections.
i've walked through debugger when initial connection , print out name of service- , hangs until press continue , socket disconnect after???
i'm new objective-c , event driven programming, perhaps i'm handling wrong? appreciate advice!
client (debugger) output:
running… 2011-05-10 14:10:26.822 client[34709:a0f] test 2011-05-10 14:10:26.850 client[34709:a0f] socket disconnected 2011-05-10 14:10:29.724 client[34709:a0f] not resolve: { nsnetserviceserrorcode = -72003; nsnetserviceserrordomain = 10; }
server output:
registering bonjour service ready= ([<dnsserviceref object @ 0x100583290>], [], []) registered service: name = test regtype = _xxx._tcp. domain = local. tcpserver waiting client on port 5000
the client code (clientcontroller.m, lifted http://www.macresearch.org/cocoa-scientists-part-xxix-message):
#import "clientcontroller.h" #import "asyncsocket.h" @interface clientcontroller () @property (readwrite, retain) nsnetservicebrowser *browser; @property (readwrite, retain) nsmutablearray *services; @property (readwrite, assign) bool isconnected; @property (readwrite, retain) nsnetservice *connectedservice; @property (readwrite, retain) mtmessagebroker *messagebroker; @end @implementation clientcontroller @synthesize browser; @synthesize services; @synthesize isconnected; @synthesize connectedservice; @synthesize socket; @synthesize messagebroker; -(void)awakefromnib { services = [nsmutablearray new]; self.browser = [[nsnetservicebrowser new] autorelease]; self.browser.delegate = self; self.isconnected = no; } -(void)dealloc { self.connectedservice = nil; self.browser = nil; self.socket = nil; self.messagebroker = nil; [services release]; [super dealloc]; } -(ibaction)search:(id)sender { [self.browser searchforservicesoftype:@"_xxx._tcp." indomain:@""]; } -(ibaction)connect:(id)sender { nsnetservice *remoteservice = servicescontroller.selectedobjects.lastobject; remoteservice.delegate = self; [remoteservice resolvewithtimeout:30]; nslog(@"%@",remoteservice.name); } -(ibaction)send:(id)sender { nsdata *data = [textview.string datausingencoding:nsutf8stringencoding]; nslog(textview.string); // use socket send raw text data once connected } #pragma mark asyncsocket delegate methods -(void)onsocketdiddisconnect:(asyncsocket *)sock { nslog(@"socket disconnected"); } -(bool)onsocketwillconnect:(asyncsocket *)sock { if ( messagebroker == nil ) { [sock retain]; return yes; } return no; } -(void)onsocket:(asyncsocket *)sock didconnecttohost:(nsstring *)host port:(uint16)port { //mtmessagebroker *newbroker = [[[mtmessagebroker alloc] initwithasyncsocket:socket] autorelease]; //[sock release]; //newbroker.delegate = self; //self.messagebroker = newbroker; self.isconnected = yes; } #pragma mark net service browser delegate methods -(void)netservicebrowser:(nsnetservicebrowser *)abrowser didfindservice:(nsnetservice *)aservice morecoming:(bool)more { [servicescontroller addobject:aservice]; } -(void)netservicebrowser:(nsnetservicebrowser *)abrowser didremoveservice:(nsnetservice *)aservice morecoming:(bool)more { [servicescontroller removeobject:aservice]; if ( aservice == self.connectedservice ) self.isconnected = no; } -(void)netservicedidresolveaddress:(nsnetservice *)service { nserror *error; self.connectedservice = service; self.socket = [[[asyncsocket alloc] initwithdelegate:self] autorelease]; [self.socket connecttoaddress:service.addresses.lastobject error:&error]; } -(void)netservice:(nsnetservice *)service didnotresolve:(nsdictionary *)errordict { nslog(@"could not resolve: %@", errordict); } @end
i having same issue. seems problem connection in place : "attempting connect while connected or accepting connections. disconnect first". unfortunately haven't been able resolve yet. idea ? might delay or ordering process problem.
edit : actually, changing connecttoaddress connecttohost made me ! :)
Comments
Post a Comment