我正在工作的UDP聊天,应该是监听和能够发送消息任何时候只用一个套接字。例如,我会有聊天程序完成,我会打开它第一次,然后第二次,我必须能够通过UDP从两个程序通信,简单地说,每个程序只有一个打开的套接字。在
我的两个线程是用来监听的,这是迪蒙线程,因为我想让它不停地听新消息,而我的另一个线程是发送消息,这和普通线程一样。在
首先,我的问题是,我的线程似乎在互相阻塞,因为如果我运行这个程序,我只能从我启动的第一个线程得到输出。在
第二个问题是,我不确定我的sending函数或整个类是否编写正确,或者是否有遗漏或不正确的地方。在
提前谢谢。顺便说一句,我是python新手,我正在使用python3,只是为了让大家明白。在
import socket
import threading
import logging
import time
from sys import byteorder
class Sending():
def __init__(self, name, tHost, tPort):
self.name = name
self.host = tHost
self.port = tPort
def set_name(self, name):
self.name = name
def send(self, name, tHost, tPort, msgType, dgramSize):
logging.debug('Starting send run')
message = input('Enter message: ')
data = bytearray()
data.extend( (name.encode('utf-8'), message.encode('utf-8'), msgType.to_bytes(1, byteorder = 'little')) )
#data.extend(message.encode(encoding='utf_8'))
self.sock.sendto(bytearray(data), (tHost, tPort))
def run(self):
th2 = threading.Thread(name = 'send', target=self.send('username', 'localhost', 8001, 1, 1400))
th2.start()
class Receiving():
def __init__(self, host, port):
self.host = host
self.port = port
def create_socket(self, host, port):
logging.debug('Starting socket')
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind((host, port))
#print ('socket ready')
time.sleep(5)
while True:
data, addr = sock.recvfrom(1500)
print('Prijata:' + data + addr)
def run(self):
th1 = threading.Thread(name = 'rec', target=self.create_socket('localhost', 8000))
th1.setDaemon(True)
th1.start()
if __name__ == '__main__':
#print ('running')
rec = Receiving('localhost', 8000)
send = Sending('username', 'localhost', 8001)
send.run()
rec.run()
恭喜你对Python的介绍!看起来您使用的是python3,在以后的问题中,如果您清楚地知道您使用的是哪个版本,这将很有帮助,因为有些代码(包括这段代码!)中存在轻微但会破坏程序的不兼容性。在
我在你的程序中发现了一些错误:
最主要的问题是,正如特雷弗·巴恩威尔所说,你打电话给
threading.Thread
并不太正确。target=
参数需要是一个可调用的对象(即函数),但在本例中它应该只是对函数的引用。如果您像上面一样给函数self.create_socket(host, port)
添加括号,它实际上会立即运行函数。正如Trevor所解释的,您的Sending.send()
方法很早就被调用了,但是Receiving
中还有一个类似的bug。因为接收.create_套接字()创建无限循环,它从不返回程序执行。虽然控制台输出在用户看来是正确的,但实际的程序执行从来没有让它在单独的线程中运行侦听器。bytearray.extend()
接受一个int的iterable,现在传递的是字节对象的元组。在
Sending.send()
中,您调用了self.sock
,但是您从未给self.sock
赋值,所以它失败了。Sending.run()
只运行Sending.send()
一次。在为用户完成输入后,它会立即退出,因为程序已经完成。如果您正在寻找一个适合有经验的程序员的基于项目的深入介绍Python(包括一个与这个问题非常相似的关于基本套接字的练习,另一个关于线程的练习),我强烈建议您查看Wesley Chun的“Core Python Applications Programming”。最新的版本(第3版)有很多python2代码,但是它很容易移植到python3,读者只需要做一些小的工作。在
我试图尽可能少地修改您的代码以使其正常工作,如下所示:
线程没有相互阻塞。
send
在创建线程之前被调用。在这条线路打电话到:
^{pr2}$我想你是想这么做的:
这样,一个线程将在下一行开始调用send。在
还有两件事:
raw_input
而不是{相关问题 更多 >
编程相关推荐