如何在TCP服务器中实现Select()模块函数



我正在尝试实现可以使用SELECT模块函数来处理客户端的TCP server,但我与

的教程混淆了
  1. select()在python的选择模块中如何工作?
  2. https://pymotw.com/2/select

我想知道。我的代码是否正确?如果不是,我该如何修复。

服务器端

import socket,sys,os,select,Queue
HOST = 'localhost'                 
PORT = 3820
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setblocking(0)
server.bind((HOST, PORT))
server.listen(5)
inputs = [ server ]
while (1):
    inputready,outputready,exceptready = select.select(inputs,[],[])
    for s in inputready:
        if s is server:
            conn, addr = server.accept()
            print 'Client connected ..'
            conn.setblocking(0)
            inputs.append(conn)
        else:
            reqCommand = conn.recv(2048)
            if reqCommand:
            print 'Client> %s' %(reqCommand)
    if (reqCommand == 'quit'):
        print 'Client disconected'
        break
    #list file on server
    elif (reqCommand == 'lls'):
        start_path = os.listdir('.') # server directory
        for path,dirs,files in os.walk(start_path):
            for filename in files:
                print os.path.join(filename)
    else:
        string = reqCommand.split(' ', 1)   #in case of 'put' and 'get' method
        reqFile = string[1] 
        if (string[0] == 'put'):
            with open(reqFile, 'wb') as file_to_write:
                while True:
                    data = conn.recv(2048)
                    # print data
                    if not data:
                        break
                    # print data
                    file_to_write.write(data)
                    file_to_write.close()
                    break
            print 'Receive Successful'
        elif (string[0] == 'get'):
            with open(reqFile, 'rb') as file_to_send:
                for data in file_to_send:
                    conn.sendall(data)
            print 'Send Successful'
conn.close()
server.close()

如果使用select,则不应设置非阻止模式,因为每个请求都不会阻止。您不使用SELECT中的输出;您必须检查,如果您想发送某些内容,是否准备就绪。

您不使用协议。recv最多可以接收1024个字节,但是您还必须处理每个recv仅读取一个字节的情况。因此,当reqCommand完成时,您必须知道(通过协议)。

使用select,您不得使用while -Loops接收更多数据。您必须在主循环中读取块,然后存储它们,直到变速箱完成为止。

使用select,您不得使用for -Loops和sendall发送数据。您必须通过select询问套接字是否准备输出数据并使用send,并且返回值才能知道已经发送了多少个字节。

您不处理封闭的连接。

最新更新