我刚开始编写python。 我的目标是建造一个有三个屏幕的数码相框。因此,我使用3个Raspis,每个监视器一个。 为了这些raspi的通信,我需要编写一个服务器和一个客户端。你知道吗
对于第一个测试,我想构建一个服务器,它能够向多个客户机发送和接收消息。 所以我从一些socket教程开始,创建了以下程序。你知道吗
服务器类(TcpServer.py文件)你知道吗
class TcpServer:
clients = []
serverIsRunning = 0
port = 0
def __init__(self, port):
self.port = port
self.serverIsRunning = 0
self.serverRunning = 0
def startServer (self):
print("start Server...")
self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server.bind(("", self.port))
self.server.listen(1)
self.serverRunning = 1
while self.serverRunning:
read, write, oob = select.select([self.server] + self.clients, [], [])
for sock in read:
if sock is self.server:
client, addr = self.server.accept()
self.clients.append(client)
print ("+++ Client ", addr[0], " verbunden")
else:
nachricht = sock.recv(1024)
ip = sock.getpeername()[0]
if nachricht:
print (ip, nachricht)
else:
print ("+++ Verbindung zu ", ip , " beendet")
sock.close()
self.clients.remove(sock)
for c in self.clients:
c.close()
self.clients.remove(c)
self.server.close()
def send(self, message):
message = message.encode()
self.server.send(message)
客户端类(TcpClient.py文件)你知道吗
import socket
class TcpClient:
def __init__(self, ip, port):
self.serverAdress = (ip, port)
self.connected = 0
self.connection = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.connection.connect(self.serverAdress)
print ("connectet to ", self.serverAdress)
def send(self, message):
message = message.encode()
self.connection.send(message)
服务器:
import threading
import TcpServer
tcpServer = TcpServer.TcpServer(50000)
threadTcpServer = threading.Thread(target = tcpServer.startServer)
threadTcpServer.start()
while True:
tcpServer.send(input("Nachricht eingeben: "))
客户:
import threading
import TcpClient
tcpClient = TcpClient.TcpClient("192.168.178.49", 50000)
while True:
tcpClient.send(input("Nachricht eingeben: "))
我可以将消息从客户端发送到服务器,但是当我要将消息从服务器发送到客户端时,它会生成以下错误:
BrokenPipeError: [Errno 32] Broken pipe
我假设这是因为服务器线程在等待传入消息时阻塞了套接字。但我不知道怎么处理。 如何编程一个可以发送和接收消息的服务器?你能推荐一个教程吗?我没有找到一个教程来描述我的问题的解决方案。你知道吗
编辑:
现在我试着用socketserver库来解决这个问题,但是我仍然不能解决这个问题。 以下是我的服务器新代码:
import socketserver
import threading
import time
class MyTCPHandler(socketserver.BaseRequestHandler):
"""
The RequestHandler class for our server.
It is instantiated once per connection to the server, and must
override the handle() method to implement communication to the
client.
"""
def handle(self):
# self.request is the TCP socket connected to the client
self.data = self.request.recv(1024).strip()
print("{} wrote:".format(self.client_address[0]))
print(self.data)
# just send back the same data, but upper-cased
self.request.sendall(self.data.upper())
if __name__ == "__main__":
HOST, PORT = "localhost", 9999
# Create the server, binding to localhost on port 9999
server = socketserver.TCPServer((HOST, PORT), MyTCPHandler)
# Activate the server; this will keep running until you
# interrupt the program with Ctrl-C
threadTcpServer = threading.Thread(target = server.serve_forever)
threadTcpServer.start()
print("server started")
time.sleep(10)
print("sending Data")
server.request.sendall("Server is sending...")
它生成错误:
AttributeError: 'TCPServer' object has no attribute 'request'
我的目标是用一个线程编写一个服务器,该线程接收数据,但仍然能够从另一个线程发送数据。 只有一个插座就可以吗?你知道吗
您应该使用提供的socketserver,而不是编写套接字和select等的所有处理
你的代码有多个问题-
1-服务器正在尝试写入侦听套接字!!客户机通信套接字是您从accept()调用获得的套接字,也是您必须用于读写的套接字。你知道吗
2-客户端正在发送数据并立即完成,但它确实应该等待得到响应。否则,python/OS将在程序完成后立即关闭客户机套接字,并且通常在服务器有机会响应之前关闭。你知道吗
我相信有了处理程序代码,您就能够在服务器上接收客户机发送的数据,也能够将一些数据从处理程序发送回客户机?您一定知道,除非有一个客户机连接到服务器,否则服务器不能将任何数据发送回去?你知道吗
现在,要从“另一个”线程向客户机(或多个客户机)发送数据,您需要一种方法使处理程序对象或客户机套接字(在处理程序对象内可用为
self.request
)对“另一个”线程可用。你知道吗一种方法是重写
def __init__(self, request, client_address, server):
方法并将this
对象的引用保存在全局列表中。记住在重写的init的最后一行执行以下操作-一旦全局列表中有了所有客户机处理程序,就可以根据需要从任何线程轻松地向所有客户机写入数据。您必须阅读有关同步(锁)的内容,并理解从多个线程使用同一对象/套接字可能会给应用程序带来一些逻辑/数据问题。你知道吗
另一件您必须担心的事情和代码是,每当客户机关闭连接时,都要清理这个全局列表。你知道吗
相关问题 更多 >
编程相关推荐