【问题标题】:Thread UDP Socket线程 UDP 套接字
【发布时间】:2015-02-18 04:28:08
【问题描述】:

我正在尝试使用 python 制作多线程 udp 服务器。

这是我正在做的事情:

#!/usr/bin/python
# -*- coding:Utf-8 -*-

import sys
import socket
from thread import start_new_thread


class Broker():
    def __init__(self, ip, port):
        self.s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self.s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.ip = ip
        self.port = port
        self.s.bind((ip, port))
        self.listclients = []

def listenMod(b):
    dic = {}
    msg, ip = b.s.recvfrom(1024)
    dic[msg] = ip
    b.listclients.append(dic)
    print msg, " is connected."


def broker(arg):
    try:
        b = Broker(arg[2], int(arg[3]))
        start_new_thread(listenMod, (b, ))

    except Exception, e:
        print e
        sys.exit(-1)


def client(arg):
    try:
        pass
    except:
        pass

def usage():
    print "usage ./udps.py <-b|-c> <args>"
    print "-b\tserver mode\n\t<args>: host port"
    sys.exit()

def main():
    i = 1
    if len(sys.argv) > 1:
        while i < len(sys.argv):
            if sys.argv[1] == "-b":
                broker(sys.argv)
            elif sys.argv[1] == "-c":
                pass
            else:
                usage()
    else:
        usage()



if __name__ == '__main__':
    main()

它总是打印“[Errno 48] 地址已在使用中”

我使用它是因为我希望能够与我的客户一起做一些特殊的事情,但也能够同时连接新客户。

【问题讨论】:

  • 您是否多次致电broker()?你不能多次将一个套接字绑定到一个端口……也许你再展示一些代码,与broker()的用法有关。
  • 不,我没有。实际上,如果我不使用它会起作用:start_new_thread(listenMod, (b, )) 但只是:listenMod(b)
  • 你的哪一行代码失败了?你能提供一个完整的工作示例程序吗?
  • 你必须展示这个类是如何被使用的。您不能两次绑定到同一个端口号 - 一个端口只能绑定一个套接字。
  • start_new_thread(listenMod, (b, )) 使我的代码失败。我调用了我的类构造函数一次。

标签: python multithreading sockets udp


【解决方案1】:

首先,不要使用SO_REUSEADDR。有legitimate uses of SO_REUSEADDR,但在大多数简单的情况下它没有用,它隐藏了真正的问题。如果需要,请随意重新添加它,但前提是您的程序在没有它的情况下也能正常工作。

您的问题在于您的main。您正在循环参数的数量,但从不增加i,因此它会无限循环。你也一直在测试argv[1]。如果有 4 个参数,第二个是 '-b',你会调用 broker() 4 次,这显然是行不通的。另外,请注意,如果您的循环结束并且主退出,您的程序将立即终止,因此您至少应该在末尾添加一个while(True): sleep(5),但这不是解决方案。

【讨论】:

  • 感谢您的回答。我使用 SO_REUSEADDR 因为我的代码旨在制作 UDP 打孔原型。
  • @ZeenaZeek 打孔不需要 SO_REUSEADDR。但是,如果您的实施需要它,那不是问题。 SO_REUSEADDR 本身并不坏,请记住它可以隐藏潜在的问题。
猜你喜欢
  • 2012-12-08
  • 2019-09-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-24
  • 2013-02-09
相关资源
最近更新 更多