Movatterモバイル変換
[0]ホーム
Muliplexing Socket Connections
Steve Holdensholden at cox.rr.com
Mon Apr 23 14:00:39 EDT 2001
"Nathan Cassano" <nathan at cjhunter.com> wrote in messagenews:3AE465F6.9FDDAD97 at cjhunter.com...> Hello Pythoneers,> I'm developing a socket server that needs to bind to and multiplexmultiple> ports. I'm using the select module and sockets to do this. The problem isI> cannot get the select function to return a file descriptor from it'sreturn read> list. Does anyone have a simple example of socket multiplexing or somepointers?>> 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 timedout and there's nothing to do, otherwise why can't you just use operate onthe sockets returned? Since select() returns lists of readable and writablesockets, you can just iterate over the lists it returns, performing theindicated operations. Or am I missing something?Here's a function extracted from a program which needs to find the MXservers for a particular domain. It's not too elegant as it was very earlyon 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
More information about the Python-listmailing list
[8]ページ先頭