Re: [Pyobjc-dev] Question about Python sockets and NSFileDescriptors
Brought to you by:
ronaldoussoren
From: Bob I. <bo...@re...> - 2004-02-20 02:03:39
|
On Feb 19, 2004, at 8:33 PM, Bob Ippolito wrote: > > On Feb 19, 2004, at 8:04 PM, Jim Clause wrote: > >> Hello, >> I've narrowed my problem down a bit more. I'm wrapping a python >> socket in an NSFileDescriptor and then registering to receive >> ConnectionAccepted notifications. When I run my code listed below I >> just get an infinite number of notifications. Can anyone see any >> errors in my code or explain why I might be getting some many >> connection notices? > > Take a look at the notification's userInfo(), those are not connection > notifications, they are EBADF errors.. Why they keep coming is beyond > me, but that's what's happening. Ok on further inspection here's what's happening: - You are creating a Python socket. When this python socket gets garbage collected, it automatically closes (hence the initial ECONNABORTED error). You need to make sure this Python socket does not get garbage collected by keeping a reference to it somewhere. - You are telling the NSFileHandle to listen to a connection over and over again. You should only do that once (hence the continuing EBADF errors). Here is a working example, slightly modified to run nibless and it has a waker so ^C can work: import socket import signal from Foundation import * from AppKit import * from PyObjCTools import AppHelper class TestServer(NSObject): def applicationDidFinishLaunching_(self, aNotification): sock = self._sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.bind((socket.gethostname(), 0)) sock.listen(5) print 'Listening on:', sock.getsockname() # Wrap the socket in an NSFileHandle using fileno() to get the # file descriptor for the socket object listeningSocket = NSFileHandle.alloc().initWithFileDescriptor_(sock.fileno()) # Register that we want to be informed of connection notifications NSNotificationCenter.defaultCenter().addObserver_selector_name_object_(s elf, "handleConnectionNotification:", NSFileHandleConnectionAcceptedNotification, listeningSocket) listeningSocket.acceptConnectionInBackgroundAndNotify() def handleConnectionNotification_(self, aNotification): print "Got Connection", aNotification.userInfo() class Waker(NSObject): def init(self): self = super(Waker, self).init() self._shouldQuit = False self._timer = NSTimer.scheduledTimerWithTimeInterval_target_selector_userInfo_repeats_ (0.5, self, self.wakeUp_, None, True) signal.signal(signal.SIGINT, self.setQuit) def wakeUp_(self, userInfo): if self._shouldQuit: NSApplication.sharedApplication().terminate_(None) self._shouldQuit = False def setQuit(self, aSignal, aStackFrame): self._shouldQuit = True if __name__ == "__main__": server = TestServer.alloc().init() app = NSApplication.sharedApplication() app.setDelegate_(server) # make ^C kill the process in a reasonable amount of time waker = Waker.alloc().init() # start app.run() |