Python3多线程socket.send()/ socket.recv()不起作用

时间:2017-06-25 18:19:10

标签: multithreading sockets python-3.6

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,如果该信息有用)

1 个答案:

答案 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.主线程然后立即关闭套接字cs。同时,线程2将进入

data = c.recv(4096).decode("UTF-8")

在主线程关闭c之前是否会读取任何数据是一种竞争条件。猜测大多数情况下主线程将在线程2从它读取之前关闭c,因此c.recv()返回一个空字节对象,导致sys.exit(1)被调用,不合情理地关闭整个程序。

我不确定你在这里尝试做什么,但threading模块对于探索多线程python编程更有用。