- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在我们类(class)的框架中,我们的老师要求我们编写一个客户端-服务器程序,其中服务器拆分两个要相乘的矩阵,然后将它们发送给客户端,客户端计算结果的一部分,然后将其发送回服务器。
我成功划分矩阵并将其发送给客户端,但我的问题是我的客户端无法将结果发送回服务器。当我尝试在服务器端接收任何消息时,我的客户端不再接收要计算的矩阵。
这是我的服务器代码
!/usr/bin/env python
# -*- coding: utf-8 -*-
from socket import socket, AF_INET, SOCK_STREAM, timeout
from threading import Thread
import numpy as np
import pickle
buf = 4096
class ErrorLevels:
OK = "OK"
ERROR = "ERREUR"
class Server(Thread):
def __init__(self):
Thread.__init__(self)
self.socket = socket(AF_INET, SOCK_STREAM)
self.socket.bind(("localhost", 2020))
self.socket.settimeout(0.5)
self.running = False
self.client_pool = []
def client_handling_stopped(self, client, error_level, error_msg):
print("Le gerant de {} s'est arrete avec le niveau d'erreur {} ({})".format(client.address[0],error_level,error_msg))
self.clean_up()
# self.log_connection_amount()
def log_connection_amount(self):
print("Il y a maintenant {} client(s) connecte(s)".format(len(self.client_pool)))
def stop(self):
print("Arrêt du serveur")
for client in self.client_pool:
client.close_connection()
self.running = False
def clean_up(self):
"""
Enleve tous les gérants de clients innactifs de la liste des gerants de clients
"""
self.client_pool = [client for client in self.client_pool if client.alive]
#le serveur genere le calcul a envoyer aux clients
#generation de matrices
def matrice_aleatoire(self,intervalle, ligne, colonne):
matrice = np.random.randint(intervalle, size=(ligne, colonne))
return matrice
def run(self):
A = self.matrice_aleatoire(10,100,100)
B = self.matrice_aleatoire(10,100,100)
#code fonctionnnant pour 10 clients
#division de A en 10 sous matrices de 10 lignes et envoie aux clients
C = np.vsplit(A, 10)
#dictionnaire a envoyer a chaque client
data = []
for i in range(10):
dic = {'num':i,'partA':C[i],'partB':B}
data.append(dic)
print("Démarrage du serveur\nAttente des connexions clients...")
self.running = True
self.socket.listen(5)
i=-1
while self.running:
try:
client, address = self.socket.accept()
i=i+1
except timeout:
continue # on retourne au début de la boucle jusqu'à avoir un client
print("Connexion depuis {}".format(address))
#envoie et reception du calcul aux clients connnectes
#actuellement 10 clients
client_handling = ClientHandling(client, address,data[i], self.client_handling_stopped)
self.client_pool.append(client_handling)
client_handling.start()
# self.log_connection_amount()
#classe d'ojbets thread pour gerer les connections clients
class ClientHandling(Thread):
def __init__(self, client, address,data, exit_callback):
Thread.__init__(self)
self.client = client
self.address = address
self.data = data
self.exit_callback = exit_callback # une fonction qui devra être appelée lorsque cet objet sera devenu inactif
self.alive = True
def _stop(self, error_level, error_msg):
self.alive = False
self.close_connection()
self.exit_callback(self, error_level, error_msg)
def close_connection(self):
self.alive = False
self.client.close()
print("Fin de la communication avec {}".format(self.address))
def run(self):
try:
#envoie du calcul
print("debut envoie du calcul")
data_string = pickle.dumps(self.data)
self.client.sendall(data_string)
print("fin envoie")
#reception resultat
'''
here is the problem when i try to receive the result
pick_ = b''
while 1:
dat = self.client.recv(buf)
pick_ += dat
print("reception resultat")
if not dat:break
res = pickle.loads(dat)
print("fin reception")
# print(res)'''
#quelques exceptions possibles
except ZeroDivisionError:
self._stop(ErrorLevels.ERROR, "Une division par zero tente")
except ConnectionAbortedError:
if self.alive: # innatendu
self._stop(ErrorLevels.ERROR, "La connexion abandonnee")
else: # on est dans le cas où le gérant est volontairement arrêté
return # on arrête donc tout, plus besoin de faire quoi que ce soit
self._stop(ErrorLevels.OK, "Le client a ferme la connection")
try:
#lancement du thread serveur
server = Server()
server.start()
while True: continue
except KeyboardInterrupt:
server.stop()
server.join()
这是我的client.py
import socket
from threading import Thread
#import numpy as np
import pickle
hote = "localhost"
port = 2020
buf = 4096
connexion_avec_serveur = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connexion_avec_serveur.connect((hote, port))
print("Connexion établie avec le serveur sur le port {}".format(port))
#thread pour le calcul du client
class Calcul(Thread):
def __init__(self):
Thread.__init__(self)
#fonction qui extrait les donnees et multiplie
def multmat(self,data):
num = data['num']
A = data['partA']
B = data['partB']
C = A @ B
resul = {'num':num,'partC':C}
return resul
def run(self):
#reception calcul
pick_str = b''
while 1:
data = connexion_avec_serveur.recv(buf)
pick_str += data
if not data:break
#connexion_avec_serveur.close()
dic = pickle.loads(pick_str)
#print(dic)
#calcul du produit
res = self.multmat(dic)
print(res)
#envoie du resultat du calcul
data_string = pickle.dumps(res)
connexion_avec_serveur.sendall(data_string)
cal = Calcul()
cal.start()
cal.join()
connexion_avec_serveur.close()
最佳答案
主要问题是客户端不知道什么时候从服务器收到了完整的消息。接收代码希望服务器在处理传入数据之前关闭连接。但是,服务器无法关闭连接,因为它正在等待客户端通过同一连接发送响应。
客户端在 data = connexion_avec_serveur.recv(buf)
处被阻塞,直到服务器关闭连接,或发生其他网络事件切断该连接。同时,服务器也在 dat = self.client.recv(buf)
处被阻塞,等待客户端的响应 - 出现死锁。
解决方案是让客户端知道何时从服务器收到完整的消息,这意味着添加一些协议(protocol)。一种方法是让服务器附加一个标记值以表示消息结束,并让客户端监视该标记。另一种方法是让服务器在消息前添加有效负载的长度,在本例中是腌制数据的长度,我在此处显示。
为客户端更改run()
函数:
import struct
def run(self):
# First 4 bytes are the length of the payload
data = connexion_avec_serveur.recv(4)
msglen = struct.unpack('!L', data)[0]
print(f'Length of payload {msglen = }')
payload = []
while msglen > 0:
print(f'{msglen = } calling recv...')
data = connexion_avec_serveur.recv(buf)
print(f'received {len(data)} bytes')
payload.append(data)
msglen -= len(data)
print(f'total bytes read {sum(len(s) for s in payload)}')
dic = pickle.loads(b''.join(payload))
#print(dic)
#calcul du produit
res = self.multmat(dic)
print(res)
#envoie du resultat du calcul
data_string = pickle.dumps(res)
connexion_avec_serveur.sendall(data_string)
对于服务器:
import struct
def run(self):
try:
#envoie du calcul
print("debut envoie du calcul")
data = pickle.dumps(self.data)
# prepend message with length of the pickled data
msg = struct.pack(f'!L{len(data)}s', len(data), data)
print(f'sending {len(msg)} bytes to client')
self.client.sendall(msg)
print("fin envoie")
#reception resultat
pick_ = b''
while True:
print('calling recv()')
dat = self.client.recv(buf)
print(f'recv() returned {len(dat)} bytes')
pick_ += dat
print("reception resultat")
if not dat:
break
res = pickle.loads(pick_)
print(f'{res = }')
print("fin reception")
#quelques exceptions possibles
except ZeroDivisionError:
self._stop(ErrorLevels.ERROR, "Une division par zero tente")
except ConnectionAbortedError:
if self.alive: # innatendu
self._stop(ErrorLevels.ERROR, "La connexion abandonnee")
else: # on est dans le cas où le gérant est volontairement arrêté
return # on arrête donc tout, plus besoin de faire quoi que ce soit
self._stop(ErrorLevels.OK, "Le client a ferme la connection")
关于python多线程服务器无法从客户端接收数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65650305/
我想在一些计算机之间建立点对点连接,这样用户就可以在没有外部服务器的情况下聊天和交换文件。我的第一个想法如下: 我在服务器上创建了一个中央 ServerSocket,所有应用程序都可以连接到该服务器。
我正在 Unity 中构建多人游戏。为此,我必须将一些值从客户端发送到两个或多个通过服务器连接的客户端。我想将其构建为服务器真实游戏。客户端将使用 Android,他们的数据将通过服务器同步(可能是一
练习 C 网络编程:我正在编写一个简单的 TCP 客户端-服务器应用程序,它应该将消息(在每个客户端的单独线程中)作为字符串从服务器发送到客户端并在客户端(稍后将成为控制台商店应用程序)。我首先发送消
我使用证书身份验证设置了 AWS Client VPN。我正在为客户端-客户端访问系统进行设置,基本上如 this AWS scenario/example 中所述.一切正常,如果我知道他们的 IP
我正在开发一个小型客户端1/客户端2、服务器(线程)TCP 游戏。在尝试处理延迟问题时,我意识到我的 transmitState() 中存在缺陷。它强制将不必要的信息传递到通讯流中,从而造成迟缓,将汽
来自文档:Configurable token lifetimes in Azure Active Directory (Public Preview) 它提到“ secret 客户端”,刷新 tok
Apollo 客户端开发工具无法连接到我的应用程序。我已在 ApolloClient 构造函数中将 connectToDevTools 传递为 true,但没有任何 react 。我也试过this p
我想在 Pod 内使用 Fabric8 kubernetes 客户端 (java)。如何获取部署集群的 kubernetes 客户端? 我可以使用该集群的 kubeconfig 文件获取任何集群的配置
我正在阅读 the security issue with Log4j我了解此产品受此漏洞影响。但是 Oracle 客户端 11.2 和 12 是否受此问题影响? 我找不到这些产品是否使用任何 Log
Eureka 服务器设置 pom.xml 1.8 Hoxton.SR1 org.springframework.cloud spring
我有一个点对点(客户端/服务器)设置(通过本地 LAN),它使用 Netty,一个 Java 网络框架。我使用原始 TCP/IP(例如,没有 HTTP)进行通信和传输。现在,根据要求,我们希望转向 T
上一篇已经实现了ModbusTcp服务器和8个主要的功能码,只是还没有实现错误处理功能。 但是在测试客户端时却发现了上一篇的一个错误,那就是写数据成功,服务器不需要响应。 接下来要做的就是实现Modb
有没有办法将二维十六进制代码数组转换为 png 图像? 数组看起来像这样(只是更大) [ [ '#FF0000', '#00FF00' ], [ '#0000FF'
我是套接字编程的新手。每次我运行客户端程序时,它都会说“无法连接到服务器”。谁能告诉我我在哪里犯了错误。任何帮助将不胜感激。 这是client.c #include #include #inclu
我们在UNIX环境下制作了简单的client.c和server.c程序。我们使用它来传输一个简单的文本文件,首先打开它,然后读取它并使用 open、read 和 send 系统调用发送;在客户端,我接
当我的程序来自 my previous question正在响应客户端,它应该发送加密消息。 当客户端连接时,它会发送一条类似“YourMessage”的消息。现在我想做的是,当客户端连接时,应该以某
我正在使用 C 和 putty 编写客户端/服务器程序。两个 c 文件位于同一系统上。 我目前在向客户端写回其正在使用的框架以及打印我的框架时遇到问题。它打印出 3 0 9 8,但随后开始打印 134
我正在使用 C 中的 select() 制作一个模拟快餐或其他任何东西的客户端服务器。 我有客户随机点 1-5 种“食物”。服务器每 30 秒决定一次。所有客户最喜欢的食物是什么?他为那些客户提供服务
对于单机游戏,基本的游戏循环是(来源:维基百科) while( user doesn't exit ) check for user input run AI move enemies
1、CentOS安装TortoiseSVN 复制代码 代码如下: yum install -y subversion 2、SVN客户端命令
我是一名优秀的程序员,十分优秀!