4

使用 Python,是否可以在本地主机和某个端口上发送 UDP 数据,然后在同一个程序中同时监听本地主机上的不同端口?我不断收到错误 48'address already in use' 并尝试使用 python 的重用地址,尽管我很确定它无论如何都不适用于此应用程序。

背景:我对软件开发一无所知,更不用说Python了,这只是有人在工作中要求的。

我很感激任何帮助。

from threading import Thread
import time
import socket


HOST = 'localhost'
PORT = 5455
PORT1 = 5457
data1 = "1"

s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((HOST,PORT1))


a = 0
def myfunction(string, *args):
    while 1:
        cmd = int( raw_input("send message: ") )
        if (cmd == 1):
            s.sendto(data1, (HOST,PORT))
            time.sleep(1)

def myfunction2(string, *args):
    while 1:
        print s.recv(30)
        time.sleep(.5)

if __name__=='__main__':

    try:
        Thread(target=myfunction, args=(a, 1)).start()
        Thread(target=myfunction2, args=(a, 1)).start()
    except Exception, errtxt:
        print errtxt
4

2 回答 2

5

是的。任何语言。您可能正在两次监听同一个端口;TCP 和 UDP 端点的特征在于 IP 地址和端口。“地址已在使用中”只会出现在完全匹配、相同地址相同端口的情况下。

此外,请确认侦听端口尚未与netstat.

更新(感谢 l4mpi):如果您在没有超级用户权限的情况下尝试使用低于 1024 的端口,您将收到“拒绝访问”。

更新

我稍微修改了你的代码;您遇到的问题之一是关于发送和接收套接字的一些混淆,这是“客户端”功能,哪个是“服务器”。

我冒昧地查询了消息正文而不是“1”,但是如果需要,很容易将其放回原处。

from threading import Thread
import time
import socket

CONN = ('localhost', 5455)

def fn_client(string, *args):
    cs = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
    cs.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    while 1:
        cmd = int( raw_input("command (1 to send): ") )
        if (cmd == 1):
            data = raw_input("message to send: ")
            cs.sendto(data, CONN)
            time.sleep(1)

def fn_server(string, *args):
    ss = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
    ss.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    ss.bind(CONN)
    while 1:
        print "Server received '%s'" % (ss.recv(30))
        time.sleep(.5)

if __name__=='__main__':

    a = 0
    try:
        Thread(target=fn_client, args=(a, 1)).start()
        Thread(target=fn_server, args=(a, 1)).start()
    except Exception, errtxt:
        print errtxt
于 2012-09-20T18:03:18.103 回答
1

你的代码对我有用,只要它不产生Address already in use.

但是您的线程代码不是太干净,KeyboardInterrupt没有在线程中处理。这是多线程的一个常见问题,请参阅此答案此配方以获取有关如何缓解它的示例。

这意味着您不能使用CTRL-C. 相反,您可能不得不求助于使用类似的东西kill [pid],甚至可能使用-9? 我的猜测是你从之前运行的程序中得到了剩余的连接,导致Address already in use. 使用类似的东西netstat -anp | grep 5457来确定该端口上是否仍有连接。

另请参阅Doug Hellman 的文章,以获得对线程的良好介绍。

于 2012-09-20T19:38:07.083 回答