我正在尝试使用非阻塞套接字在python中实现客户端服务器的一个非常基本的代码。我已经制作了两个读写线程。
我的客户端代码如下。
import sys
import socket
from time import sleep
from _thread import *
import threading
global s
def writeThread():
while True:
data = str(input('Please input the data you want to send to client 2 ( to end connection type end ) : '))
data = bytes(data, 'utf8')
print('You are trying to send : ', data)
s.sendall(data)
def readThread():
while True:
try:
msg = s.recv(4096)
except socket.timeout as e:
sleep(1)
print('recv timed out, retry later')
continue
except socket.error as e:
# Something else happened, handle error, exit, etc.
print(e)
sys.exit(1)
else:
if len(msg) == 0:
print('orderly shutdown on server end')
sys.exit(0)
else:
# got a message do something :)
print('Message is : ', msg)
if __name__ == '__main__':
global s
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('',6188))
s.settimeout(2)
wThread = threading.Thread(None,writeThread)
rThread = threading.Thread(None,readThread)
wThread.start()
rThread.start()
s.close()
问题:
我知道这也可以通过select模块实现,但我想知道如何这样做。
答案 0 :(得分:0)
您的主线程创建套接字,然后创建thread1和thread2。然后它关闭套接字(并退出,因为程序在此之后结束)。因此,当thread1和thread2尝试使用它时,它不再打开。因此EBADF
(错误的文件描述符错误)。
当其他线程仍在运行时,主线程不应关闭套接字。它可以等待它们结束:
[...]
s.settimeout(2)
wThread = threading.Thread(None,writeThread)
rThread = threading.Thread(None,readThread)
wThread.start()
rThread.start()
wThread.join()
rThread.join()
s.close()
但是,由于主线程没有比等待更好的事情,所以最好只创建一个额外的线程(比如说rThread
),然后让主线程接管当前正在执行的任务。其他。即。
[...]
s.settimeout(2)
rThread = threading.Thread(None,readThread)
rThread.start()
writeThread()