【问题标题】:How to implement select() module function in TCP server如何在 TCP 服务器中实现 select() 模块功能
【发布时间】:2018-05-07 17:42:22
【问题描述】:

我正在尝试实现TCP server,它可以通过使用选择模块功能来处理客户端,但我对来自

的教程感到困惑
  1. How does the select() function in the select module of Python exactly work?
  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()

【问题讨论】:

  • 怎么看?这是正确的吗?你试过了吗?它有效吗?例如,当第一个连接到达时,我“感知”到 NameErrorreqCommand
  • 将每个导入放在单独的行中。从ifs 中删除括号。使用while True:
  • 我尝试使用 put 命令进行测试,但它停留在 'quit' 状态,我还没有完成它 "NameError: name 'reqCommand' is not defined'。我通过了上面的代码。所以,如果我走对了路。我只想知道。接下来我应该用“put”和“get”命令做什么。@CristiFati

标签: python sockets select ubuntu-16.04 tcpserver


【解决方案1】:

如果你使用select你不应该设置非阻塞模式,因为每个请求都不会阻塞。您不要在选择中使用输出;如果你想发送一些东西,你必须检查输出是否准备好。

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

对于select,您不能使用while-loops 来接收更多数据。您必须在主循环中读取块并存储它们,直到传输完成。

对于select,您不得使用for-loops 和sendall 发送数据。您必须通过select 询问套接字是否准备好输出数据并使用send 和它的返回值来知道已经发送了多少字节。

你不处理关闭的连接。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-01
    • 1970-01-01
    • 2019-07-27
    • 2018-12-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多