"Nathan Cassano" <nathan at cjhunter.com> wrote in message news:3AE465F6.9FDDAD97 at cjhunter.com... > Hello Pythoneers, > I'm developing a socket server that needs to bind to and multiplex multiple > ports. I'm using the select module and sockets to do this. The problem is I > cannot get the select function to return a file descriptor from it's return read > list. Does anyone have a simple example of socket multiplexing or some pointers? > > import socket, select > > sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) > sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) > sock.setblocking(0) > > print select.select([sock],[sock] ,[] , 0) > > ... > > This is the output that follows > > ([], [<socket object, fd=3, family=2, type=1, protocol=0>], []) > The point, surely, is that if select() returns [[], [], []] then it timed out and there's nothing to do, otherwise why can't you just use operate on the sockets returned? Since select() returns lists of readable and writable sockets, you can just iterate over the lists it returns, performing the indicated operations. Or am I missing something? Here's a function extracted from a program which needs to find the MX servers for a particular domain. It's not too elegant as it was very early on in my Python socket career. Look for the added "##" comments below... HTH Steve # # Read dnslib.py if you really need to understand this code, # which generates a DNS request for MX records and decodes # the reply using functionality implemented in dnslib. # def MXlist(qname, server): """Return a list of MX exchangers for a given domain. This code is based on the dnslib library, and is complicated by the necessity to handle UDP errors where no response is generated by (or at least received from) the remote host.""" global mxdict # Cacheing dictionary if mxdict.has_key(qname): lf.log("[[[ Domain %s MX hosts were cached" % (qname, )) return mxdict[qname] protocol = 'udp' # This is bogus: not used anywhere! port = 53 opcode = dnsopcode.QUERY rd = 1 # server should recurse qtype = dnstype.MX m = dnslib.Mpacker() m.addHeader(0, 0, opcode, 0, 0, rd, 0, 0, 0, 1, 0, 0, 0) m.addQuestion(qname, qtype, dnsclass.IN) request = m.getbuf() s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.setblocking(0) # We need a non-blocking socket s.connect((server, port)) r, w, e = select.select([s], [s], [s], 15) ## ## Here I seem to assume a valid return means the socket ## is writable ... told you I wasn't proud of the code! ## if [r, w, e] == [[], [], []]: lf.debug("!!! Connect timed out in MXlist") return [] ## ## So I just send on it! ## s.send(request) r, w, e = select.select([s], [s], [s], 15) if [r, w, e] == [[], [], []]: lf.debug("!!! Send timed out in MXlist") return [] ## ## Since the socket has now stopped blocking, I think the ## following select is probably completely redundant ## r,w,e = select.select([s], [], [], 15.0) ## ## The above call is waiting for the socket to become readable ## if r: reply = s.recv(2048) ## ## Now it is, I just receive on it ## else: s.close() raise Timeout("Recv timed out in MXlist") ## ## No other return from select() is any use in my case ## ## The rest of the code is irrelevant ## u = dnslib.Munpacker(reply) (id, qr, opcode, aa, tc, rd, ra, z, rcode, qdcount, ancount, nscount, arcount) = u.getHeader() for i in range(qdcount): qname, qtype, qclass = u.getQuestion() MX = [] for i in range(ancount): name, type, klass, ttl, rdlength = u.getRRheader() MX.append([u.get16bit(), u.getname()]) MX.sort() servers = [] for mx in MX: servers.append(string.lower(mx[1])) s.close() mxdict[qname] = servers lf.log("[[[ %d candidate mail exchangers for %s: %s" % (len(servers), qname, string.join(servers, ", "))) return servers
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4