[英]Running server and client python scripts from a single python script or GUI button
我一直在使用 python 服务器和客户端通信。 为了建立连接,通常,服务器需要先从单独的 python 脚本运行客户端,然后再运行客户端。
我现在想要的是让它自动化。 我想从单个 python 脚本或 GUI 按钮运行服务器和客户端。 我一直在尝试不同的方法,比如多处理和多线程,但它不起作用。
请指教。
下面的示例服务器和客户端代码:
服务器.py
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('0.0.0.0', 5005))
s.listen(1)
conn, addr = s.accept()
while 1:
data = conn.recv(1024)
print("received data",list(data))
if not data:
break
conn.sendall(data)
conn.close()
客户端.py
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('0.0.0.0', 5005))
message = bytearray([1])
s.sendall(message)
data = s.recv(1024)
s.close()
print ('Received', repr(data))
我们可以通过分配两个不同的函数来处理它。 几点注意事项:
"0.0.0.0"
意味着它已准备好接受来自任何地方的连接。 另一方面,当您在计算机上运行客户端时,您应该连接到localhost
或127.0.0.1
而不是连接到0.0.0.0
。import threading
import socket
stream_lock = threading.Lock()
def server_func():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('0.0.0.0', 5005))
s.listen(1)
conn, addr = s.accept()
while 1:
data = conn.recv(1024)
# Getting printing stream lock is important
stream_lock.acquire()
print("received data", list(data))
stream_lock.release()
if not data:
break
conn.sendall(data)
conn.close()
def client_func():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('127.0.0.1', 5005))
message = bytearray([1, 2, 3])
s.sendall(message)
data = s.recv(1024)
s.close()
stream_lock.acquire()
print('Received', repr(data))
stream_lock.release()
t_server = threading.Thread(target=server_func).start()
t_client = threading.Thread(target=client_func).start()
# Output:
# received data [1, 2, 3]
# Received b'\x01\x02\x03'
我将@aminrd 的答案转换为 class object 并添加一些代码来存储从客户端接收到的数据还为需要了解每个步骤的人添加了一些注释
import socket
import threading
import json
import time
class Communication:
stream_lock = threading.Lock() # creating thread lock object
def __init__(self):
self.clientSocket = None
self.serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # create socket and store
self.STORED_DATA = {"function_name": "", "data": ""} # sample stored data
self.th = [] # threads list
def server(self):
self.serverSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,
1) # make reusing adress with different port
self.serverSocket.bind(('0.0.0.0', 5005)) # bind socket with port
self.serverSocket.listen(2) # permitted client number
print("Server is listening")
while True:
client, address = self.serverSocket.accept() # welcome new client
# send client data to new thread and process
self.th.append(threading.Thread(target=self.listener, daemon=True, args=(client,)).start())
def listener(self, client):
while True:
data = client.recv(2048) # receive new data to store
if data:
# you can get data from any client and puch data to all clients(multiple status monitors)
data_variable = json.loads(data.decode('utf-8')) # decode byte to dict
self.stream_lock.acquire() # i'm not sure about usage of lock. wrong place ?
if 'command' in data_variable and data_variable['command'] == 'write':
self.STORED_DATA = data_variable
else:
# or you can do some server stuff and manipulate data
self.STORED_DATA['function_name'] = 1
self.STORED_DATA['data'] = 1
self.stream_lock.release()
data_string = json.dumps(self.STORED_DATA).encode('utf-8') # convert stored data to bytes
client.sendall(data_string) # now send stored data to all clients
def client(self):
self.clientSocket.connect(('127.0.0.1', 5005)) # connect to server
# this function is callable from outside of class
# you can give new data to client to send to server
def receive(self, new_data_string):
self.clientSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # create socket for client
self.clientSocket.connect(('127.0.0.1', 5005)) # connect to server
data_string = json.dumps(new_data_string).encode('utf-8') # convert data to bytes
self.clientSocket.send(data_string) # send to server
data = self.clientSocket.recv(2048) # receive server data
if not data:
print("no data")
self.clientSocket.close()
data_variable = json.loads(data.decode('utf-8')) # convert data to dict
self.stream_lock.acquire()
self.stream_lock.release()
self.clientSocket.close()
return data_variable # return received data
if __name__ == "__main__":
x = Communication()
t_server = threading.Thread(target=x.server, daemon=True).start()
read = {"command": "read", "function_name": "", "data": ""}
result = x.receive(read)
print('Client Received', repr(result))
time.sleep(1)
write = {"command": "write", "function_name": "2", "data": "2"}
result = x.receive(write)
print('Client Received', repr(result))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.