请教python中select服务器编程中的使用

seai 2014-01-24 08:28:38
#server
import select
import socket
import sys

host = ''
port = 50000
backlog = 5
size = 1024
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)

server.setblocking(0)

server.bind((host,port))
server.listen(backlog)
inputs = [server]
outputs = []
running = 1

while running:
inputready,outputready,exceptready = select.select([server],[],[]) #为什么使用[],[server],[]参数的话,下面的代码总是执行不到?
print (inputready,outputready,exceptready)




#client
import socket
import time
s=socket.socket()
#s.setblocking(0)
s.connect(("",50000))
#s.setblocking(0)
#time.sleep(20)
s.send('234234')
data=s.recv(512)
print data
s.close()
...全文
197 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
angel_su 2014-01-27
  • 打赏
  • 举报
回复
到处select造成代码逻辑混乱而已,认真把while里的分支条件写好来... while 1: r, w, e = select.select(inputs, outputs... for s in r: ... for s in w: ... for s in e: ... ...里只对inputs/ouputs做append,remove动作,不要再重复调用select了
seai 2014-01-26
  • 打赏
  • 举报
回复
引用 1 楼 angel_su 的回复:
select没设定timeout是阻塞式调用,你的服务器开始只有监听端口,所以server要放到第一个列表里,等建客户端立连接后,再按需修改参数...
所以,服务端一定是先发送后接受,客户端一定是先接收后发送吗?好像不对的吧。
seai 2014-01-26
  • 打赏
  • 举报
回复
#server
import select
import socket
import sys
import Queue

# Create a TCP/IP socket
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.setblocking(0)

# Bind the socket to the port
server_address = ('localhost', 10000)
print >>sys.stderr, 'starting up on %s port %s' % server_address
server.bind(server_address)

# Listen for incoming connections
server.listen(5)

# Sockets from which we expect to read
inputs = [ server ]

# Sockets to which we expect to write
outputs = [ ]

# Outgoing message queues (socket:Queue)
message_queues = {}

while True:

    # Wait for at least one of the sockets to be ready for processing
    print >>sys.stderr, '\nwaiting for the next event'
    readable, writable, exceptional = select.select(inputs, outputs, inputs)
    print "1:",readable, writable, exceptional 

    for s in readable:
        if s is server:
            connection, client_address = s.accept()
            connection.setblocking(0)
            r,w,e = select.select([connection],[connection],[])
            print "2:",r,w,e
            for s1 in r:
                data=s1.recv(1024)  #这里执行不到
                if data:
                    print data
            for s1 in w:
                s1.send("server")

#client
import socket
s=socket.socket()
s.connect(("",10000))
data=s.recv(512)
print data
s.send('client')
s.close()
受楼上朋友提醒,下了这段代码,结果,服务器接收不到客户端的数据,只有将客户端改为先发送后接收,才能收到客户端发来的数据,这又是什么原因呢?
angel_su 2014-01-26
  • 打赏
  • 举报
回复
貌似定位服务器就是接受请求后才做事,所以看到在accept后,只先inputs.append,然后收到后才outputs.append。可是没规定你不能先outputs.append再inputs.append,或者2者同时....想咋搞自己改代码试试吧。
seai 2014-01-26
  • 打赏
  • 举报
回复
引用 3 楼 angel_su 的回复:
服务器和客户端之间是先发还是先收当然是没有限定,但监听的套接字只是用来获得新连接的套接字,把它们加入select参数列表里,用这些新的套接字收发实际的数据...
问题在于,我按上面的方式写服务端的时候,只能先发送后接受,不知道怎样才能让服务端,能够更灵活的支持不限定发送接收顺序。 比如下面这段代码:
import select
import socket
import Queue
 
#create a socket
server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server.setblocking(False)
#set option reused
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR  , 1)
 
server_address= ('192.168.1.102',10001)
server.bind(server_address)
 
server.listen(10)
 
#sockets from which we except to read
inputs = [server]
 
#sockets from which we expect to write
outputs = []
 
#Outgoing message queues (socket:Queue)
message_queues = {}
 
#A optional parameter for select is TIMEOUT
timeout = 20
 
while inputs:
    print "waiting for next event"
    readable , writable , exceptional = select.select(inputs, outputs, inputs, timeout)
 
    # When timeout reached , select return three empty lists
    if not (readable or writable or exceptional) :
        print "Time out ! "
        break;   
    for s in readable :
        if s is server:
            # A "readable" socket is ready to accept a connection
            connection, client_address = s.accept()
            print "    connection from ", client_address
            connection.setblocking(0)
            inputs.append(connection)
            message_queues[connection] = Queue.Queue()
        else:
            data = s.recv(1024)
            if data :
                print " received " , data , "from ",s.getpeername()
                message_queues[s].put(data)
                # Add output channel for response   
                if s not in outputs:
                    outputs.append(s)
            else:
                #Interpret empty result as closed connection
                print "  closing", client_address
                if s in outputs :
                    outputs.remove(s)
                inputs.remove(s)
                s.close()
                #remove message queue
                del message_queues[s]
    for s in writable:
        try:
            next_msg = message_queues[s].get_nowait()
        except Queue.Empty:
            print " " , s.getpeername() , 'queue empty'
            outputs.remove(s)
        else:
            print " sending " , next_msg , " to ", s.getpeername()
            s.send(next_msg)
     
    for s in exceptional:
        print " exception condition on ", s.getpeername()
        #stop listening for input on the connection
        inputs.remove(s)
        if s in outputs:
            outputs.remove(s)
        s.close()
        #Remove message queue
        del message_queues[s]
angel_su 2014-01-26
  • 打赏
  • 举报
回复
服务器和客户端之间是先发还是先收当然是没有限定,但监听的套接字只是用来获得新连接的套接字,把它们加入select参数列表里,用这些新的套接字收发实际的数据...
angel_su 2014-01-25
  • 打赏
  • 举报
回复
select没设定timeout是阻塞式调用,你的服务器开始只有监听端口,所以server要放到第一个列表里,等建客户端立连接后,再按需修改参数...

37,719

社区成员

发帖
与我相关
我的任务
社区描述
JavaScript,VBScript,AngleScript,ActionScript,Shell,Perl,Ruby,Lua,Tcl,Scala,MaxScript 等脚本语言交流。
社区管理员
  • 脚本语言(Perl/Python)社区
  • IT.BOB
加入社区
  • 近7日
  • 近30日
  • 至今

试试用AI创作助手写篇文章吧