【问题标题】:How to keep listening to the connected TCP sockets by "select"如何通过“选择”继续监听连接的 TCP 套接字
【发布时间】:2016-02-09 15:01:19
【问题描述】:

我所有的客户端套接字都做同样的事情:每秒发送一个包(22 字节)

服务器代码如下:

import select
import socket
import datetime
SList = []


class Tserver:

    def __init__(self, portNum):
        host = '127.0.0.1'
        self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.server.bind((host, portNum))
        self.server.listen(1)


def GETPACK():
    # function for CRC check
    def CRC(DATA_STR):
        return 1

    # generate 100 sockets to listen
    for x in range(100):
        SList.append(Tserver(x+10000))

    inputs = []
    # put in inputs
    for x in range(100):
        inputs.append(SList[x].server)

    while(True):
        ready_socks, _, _ = select.select(inputs, [], [])
        for sock in ready_socks:
            c, addr = sock.accept()
            while(True):
                data = c.recv(22)
                if len(data) == 22:  # To make sure the data-length is 22
                    # Turn the pack string into bytearray
                    data_bytes = bytearray()
                    data_bytes.extend(data)
                    if CRC(data_bytes) == 1:
                        print "Connected from client IP Address:" + str(addr)
                        # ID
                        ID = 256*data_bytes[1] + data_bytes[2]
                        print "ID: ", ID
                        now = datetime.datetime.now()
                        print "now: ", str(now)

if __name__ == "__main__":
    GETPACK()

我的服务器只能打印第一个连接的套接字发送的包。 我的问题是如何在将包发送到服务器时打印出每个端口的所有消息。

【问题讨论】:

  • 您是否尝试调试过您的代码?
  • 套接字不能这样工作。您应该重新阅读我相信的套接字文档。您只需创建一个套接字来侦听一个端口,然后accept 将为每个连接返回一个新创建的套接字。
  • @peterh 不是真的,我还在努力。需要一些好的建议。

标签: python sockets select tcp


【解决方案1】:

@ErikR 感谢您的帮助,我更改了代码,并且运行良好。

我的代码不起作用的原因有两个:

1.我只创建一个连接来接收来自我的客户的数据。

2.如果客户端未重新连接,recv 将无法再次接受相同的连接。(我的代码在客户端关闭时不检查异常)

代码如下:

import select, socket, datetime
SList = []
SconnList = []

class Tserver:
    def __init__(self, portNum):
        host = '127.0.0.1'
        self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,1)
        self.server.bind((host,portNum))
        self.server.listen(1)
        print "Server ports: "+str(portNum)

class Sconn:
    def __init__(self, sock):
        self.conn, self.addr = sock.accept()        

def GETPACK():
    # function for CRC check
    def CRC(DATA_STR):
        return 1

    # generate 100 sockets to listen        
    for x in range(100):
        SList.append(Tserver(x+10000))

    inputs = []
    # put in inputs
    for x in range(100):
        inputs.append(SList[x].server)

    while(True):
        ready_socks,_,_ = select.select(inputs, [], [])
        for sock in ready_socks:
            try:
                SconnList.append(Sconn(sock))
                SconnList.reverse()
                inputs.append(SconnList[0].conn)
            except:     
                data = sock.recv(22)
                if len(data) == 22: # To make sure the data-length is 22
                #Turn the pack string into bytearray
                    data_bytes = bytearray()
                    data_bytes.extend(data)
                    if CRC(data_bytes) == 1:
                        print "IP Address:" + str(sock.getsockname())
                        #ID
                        ID = 256*data_bytes[1] + data_bytes[2]
                        print "ID: ",ID
                        now =  datetime.datetime.now()
                        print "now: ",str(now)
                        print ""
                        print ""

if __name__ == "__main__":
    GETPACK() 

【讨论】:

    【解决方案2】:

    有关如何使用select 模块编写基于选择的服务器的详细说明,请参阅this PyMOTW entry

    该示例与您的代码之间的主要区别是:

    您只需创建一个侦听套接字 - server。无需监听多个端口。

    变量inputs 将是一个列表,其中包含server 和与客户端的任何其他打开的套接字连接。

    您的服务循环将如下所示:

    while true:
      readable, _, _ = select.select(inputs, [], [])
      for r in readable:
        if r is server:
          # handle a new incoming connection
          # this will add an entry to the variable inputs
        else:
          # read some data from socket r and process it
    

    当您尝试从客户端套接字读取并获得 EOF 条件时,您可以关闭该套接字并将其从 inputs 变量中删除。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-10-16
      • 2015-03-05
      • 2016-04-06
      • 2012-07-27
      • 2013-06-08
      • 1970-01-01
      • 2011-03-31
      • 2020-05-28
      相关资源
      最近更新 更多