server.py代码:
import socket
import _thread
import sys
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(('x.x.x.x', xxxx))
s.listen(1)
print("Server is running.")
c, a = s.accept()
print('[+] CONNECTED: {}:{} [+]'.format(a[0],a[1]))
c.send(b'[+] CONNECTED [+]\n')
def recv():
while 1:
data = c.recv(4096).decode("UTF-8")
if not data: sys.exit(0)
print(data)
def send():
while 1:
msg = input("Msg: ")
c.send(msg.encode('UTF-8'))
_thread.start_new_thread(send(), ())
_thread.start_new_thread(recv(), ())
c.close()
s.close()
谷歌搜索问题,我认为我应该这样做。但是,它似乎不起作用。
如果将send()或recv()设置为第一个,我会卡在一个上,而不会让另一个运行。就像我在没有线程模块的情况下使用这些功能一样。
有人解释我犯错的地方吗?我很感激。
(我正在使用netcat连接到服务器btw,如果该信息有用)
答案 0 :(得分:0)
线程可能很复杂,所以我会尝试分析可能发生的事情。首先,在你的问题中你有
_thread.start_new_thread(send(), ())
_thread.start_new_thread(recv(), ())
自send()
执行以来,这并没有多大意义,并且会立即进入无限循环。 _thread.start_new_thread()
期望第一个参数的函数,所以如果改为将这些行更改为更有意义:
_thread.start_new_thread(send, ())
_thread.start_new_thread(recv, ())
现在让我们看一下如果执行该代码会发生什么。首先,主线程开始并在
处阻塞c, a = s.accept()
直到客户端连接。然后主线程继续并启动运行send
函数的线程2,并启动运行recv
函数的线程3。此时你有3个线程在运行:主线程,线程2和线程3.主线程然后立即关闭套接字c
和s
。同时,线程2将进入
data = c.recv(4096).decode("UTF-8")
在主线程关闭c
之前是否会读取任何数据是一种竞争条件。猜测大多数情况下主线程将在线程2从它读取之前关闭c
,因此c.recv()返回一个空字节对象,导致sys.exit(1)
被调用,不合情理地关闭整个程序。
我不确定你在这里尝试做什么,但threading
模块对于探索多线程python编程更有用。