Python select 用于 python 程序
Python select used in python program
我正在阅读使用 python
开发的 proxy server
我不明白使用select
编写客户端和服务器套接字的方法def _read_write
。
def _read_write(self):
time_out_max = self.timeout/3
socs = [self.client, self.target]
count = 0
while 1:
count += 1
(recv, _, error) = select.select(socs, [], socs, 3)
if error:
break
if recv:
for in_ in recv:
data = in_.recv(BUFLEN)
if in_ is self.client:
out = self.target
else:
out = self.client
if data:
out.send(data)
count = 0
if count == time_out_max:
break
请懂的人帮我理解。
这是我的粗略注释:
def _read_write(self):
# This allows us to get multiple
# lower-level timeouts before we give up.
# (but see later note about Python 3)
time_out_max = self.timeout/3
# We have two sockets we care about
socs = [self.client, self.target]
# Loop until error or timeout
count = 0
while 1:
count += 1
# select is very efficient. It will let
# other processes execute until we have
# data or an error.
# We only care about receive and error
# conditions, so we pass in an empty list
# for transmit, and assign transmit results
# to the _ variable to ignore.
# We also pass a timeout of 3 seconds, which
# is why it's OK to divide the timeout value
# by 3 above.
# Note that select doesn't read anything for
# us -- it just blocks until data is ready.
(recv, _, error) = select.select(socs, [], socs, 3)
# If we have an error, break out of the loop
if error:
break
# If we have receive data, it's from the client
# for the target, or the other way around, or
# even both. Loop through and deal with whatever
# receive data we have and send it to the other
# port.
# BTW, "if recv" is redundant here -- (a) in
# general (except for timeouts) we'll have
# receive data here, and (b) the for loop won't
# execute if we don't.
if recv:
for in_ in recv:
# Read data up to a max of BUFLEN,
data = in_.recv(BUFLEN)
# Dump the data out the other side.
# Indexing probably would have been
# more efficient than this if/else
if in_ is self.client:
out = self.target
else:
out = self.client
# I think this may be a bug. IIRC,
# send is not required to send all the
# data, but I don't remember and cannot
# be bothered to look it up right now.
if data:
out.send(data)
# Reset the timeout counter.
count = 0
# This is ugly -- should be >=, then it might
# work even on Python 3...
if count == time_out_max:
break
# We're done with the loop and exit the function on
# either a timeout or an error.
我正在阅读使用 python
开发的 proxy server我不明白使用select
编写客户端和服务器套接字的方法def _read_write
。
def _read_write(self):
time_out_max = self.timeout/3
socs = [self.client, self.target]
count = 0
while 1:
count += 1
(recv, _, error) = select.select(socs, [], socs, 3)
if error:
break
if recv:
for in_ in recv:
data = in_.recv(BUFLEN)
if in_ is self.client:
out = self.target
else:
out = self.client
if data:
out.send(data)
count = 0
if count == time_out_max:
break
请懂的人帮我理解。
这是我的粗略注释:
def _read_write(self):
# This allows us to get multiple
# lower-level timeouts before we give up.
# (but see later note about Python 3)
time_out_max = self.timeout/3
# We have two sockets we care about
socs = [self.client, self.target]
# Loop until error or timeout
count = 0
while 1:
count += 1
# select is very efficient. It will let
# other processes execute until we have
# data or an error.
# We only care about receive and error
# conditions, so we pass in an empty list
# for transmit, and assign transmit results
# to the _ variable to ignore.
# We also pass a timeout of 3 seconds, which
# is why it's OK to divide the timeout value
# by 3 above.
# Note that select doesn't read anything for
# us -- it just blocks until data is ready.
(recv, _, error) = select.select(socs, [], socs, 3)
# If we have an error, break out of the loop
if error:
break
# If we have receive data, it's from the client
# for the target, or the other way around, or
# even both. Loop through and deal with whatever
# receive data we have and send it to the other
# port.
# BTW, "if recv" is redundant here -- (a) in
# general (except for timeouts) we'll have
# receive data here, and (b) the for loop won't
# execute if we don't.
if recv:
for in_ in recv:
# Read data up to a max of BUFLEN,
data = in_.recv(BUFLEN)
# Dump the data out the other side.
# Indexing probably would have been
# more efficient than this if/else
if in_ is self.client:
out = self.target
else:
out = self.client
# I think this may be a bug. IIRC,
# send is not required to send all the
# data, but I don't remember and cannot
# be bothered to look it up right now.
if data:
out.send(data)
# Reset the timeout counter.
count = 0
# This is ugly -- should be >=, then it might
# work even on Python 3...
if count == time_out_max:
break
# We're done with the loop and exit the function on
# either a timeout or an error.