[英]python TCP communication threaded, delay and error
I would like to ask you a question about a trouble i found while i was coding to improve my skill in TCP communication. 我想问一个问题,我在编码时发现了麻烦,以提高我在TCP通信中的技能。 Basically i first learn about socket and how to open server/client socket and communication.
基本上,我首先了解套接字以及如何打开服务器/客户端套接字和通信。 So i wrote one class for server and one for client, i test it and i found they work very fine for what i care: this is the server
因此,我为服务器编写了一个类,为客户端编写了一个类,我对其进行了测试,发现它们可以很好地满足我的需求:这就是服务器
class server_class:
def __init__(self, sock=None):
if sock is None:
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
else:
self.sock = sock
def bind(self,host, port):
self.sock.bind((host, port))
def listen(self,client):
self.sock.listen(client)
def close_client(self):
self.client.close()
def accept(self):
self.client,self.c_addr=self.sock.accept()
def invia(self,MSGLEN,msg):
totalsent = 0
if(len(msg)<MSGLEN):
while(len(msg)<MSGLEN):
msg=msg+'*'
while totalsent < MSGLEN:
sent = self.client.send(msg[totalsent:].encode('ascii'))
if sent == 0:
raise RuntimeError
totalsent = totalsent + sent
def ricevi(self,MSGLEN):
msg = ''
while len(msg) < MSGLEN:
chunk = self.client.recv(MSGLEN-len(msg)).decode('ascii')
if chunk == '':
raise RuntimeError
msg = msg + chunk
i=0
messaggio=''
while(i<MSGLEN):
if(msg[i]!='*'):
mess=msg[i]
messaggio=messaggio+mess
else:
pass
i+=1
return messaggio
and this is the client: 这是客户:
class client_class:
def __init__(self, sock=None):
if sock is None:
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
else:
self.sock = sock
def connect(self,host,port):
self.sock.connect((host, port))
def invia(self,MSGLEN,msg):
totalsent = 0
if(len(msg)<MSGLEN):
while(len(msg)<MSGLEN):
msg=msg+'*'
while totalsent < MSGLEN:
sent = self.sock.send(msg[totalsent:].encode('ascii'))
if sent == 0:
raise RuntimeError
totalsent = totalsent + sent
def ricevi(self,MSGLEN):
msg = ''
while len(msg) < MSGLEN:
chunk = self.sock.recv(MSGLEN-len(msg)).decode('ascii')
if chunk == '':
raise RuntimeError
msg = msg + chunk
i=0
messaggio=''
while(i<MSGLEN):
if(msg[i]!='*'):
mess=msg[i]
else:
pass
messaggio=messaggio+mess
i+=1
return messaggio
So no at all problem at this time. 因此,目前没有任何问题。 Next step i tried to do was to write a program that while doing some math or GUI or both, keep a server on for communicate to a client the information it work out in math for example.
我试图做的下一步是编写一个程序,在做一些数学运算或GUI或同时进行这两项运算时,保持服务器运行,以便与客户端交流例如在数学运算中得出的信息。 The only way i found to do this is use threading module.
我发现做到这一点的唯一方法是使用线程模块。 I write 2 function, one for server and one for math (increase x value in while loop) and add in main a GUI.
我编写了2个函数,一个用于服务器,一个用于数学运算(在while循环中增加x值),并在主界面中添加一个GUI。 Then i pass each function to a thread.
然后,我将每个函数传递给线程。 This is the server function (that use server class defined before):
这是服务器功能(使用之前定义的服务器类):
def server():
global Stop,x
server=server_class()
ip='192.168.1.134'
port=8033
server.bind(ip,port)
Stop=True
client=0
c_addr=0
while(Stop):
server.listen(1)
print("* inizio ascolto su",ip,":",port)
server.accept()
print("* mi sono connesso con",server.c_addr[0],":",server.c_addr[1])
while(Stop):
data=server.ricevi(100)
print(data)
if(data=="disconnetti"):
msg="bye bye"
server.invia(100,msg)
server.close_client()
print("*disconnetto il client")
break
if(data=="inviami x"):
msg=str(x)
server.invia(100,msg)
if(data=="chiudi server"):
print("*chiudo server")
server.close_client()
Stop=False
else:
msg="come?"
server.invia(100,msg)
This is the math function named 'go': 这是名为“ go”的数学函数:
def go():
global x
while(x<10000):
x+=1
time.sleep(1)
Finally the main function is: 最后,主要功能是:
finestra=Tk()
finestra.geometry('800x800+300+300')
finestra.title('Prova threading')
testo_0=Label(finestra,text="Valore attuale:").grid(sticky=W,row=0,column=0)
gobutton=Button(finestra,text='Acquisisci',command=lambda: leggi())
gobutton.grid(row=2, column=1)
goo=threading.Thread(target=go)
serv=threading.Thread(target=server)
goo.start()
serv.start()
finestra.mainloop()
So go function increase continuously x value, server function keep a server listening and main thread keep a GUI within which a user can see x value by pressing a botton. 因此go函数连续增加x值,服务器功能保持服务器监听,而主线程保持GUI,用户可以通过在其中按下按钮来查看x值。 The server knows just 3 commands from client: 1)pass x to client 2)close client 3)close server for other message it answer as unknown command.
服务器只知道来自客户端的3条命令:1)将x传递给客户端2)关闭客户端3)关闭服务器以获取其他消息,它作为未知命令回答。 What happen is that the communication doesn't work good;
发生的情况是沟通无法正常进行。 for example when from a client (running on other machine using the client class defined before) ask to server to pass x value (that go function is constantly increasing) happen 2 wrong things: 1) After the first communication other seems delayed, for example the second time i ask x value the server answer as unknown command, third time i send a request for x value it give me a value.
例如,当从客户端(使用之前定义的客户端类在其他计算机上运行)要求服务器传递x值(go函数不断增加)时,发生2件错误的事情:1)在第一次通信之后,其他似乎延迟了,例如第二次我问x值服务器答案作为未知命令,第三次我发送对x值的请求,它给了我一个值。 Next time its going to answer as unknown and next give me a value and so on.
下次它会以未知的方式回答,接下来给我一个值,依此类推。 2) After the first communication too, the values that server pass to client are delayed, so for example if at the same time i send to server request for x and push the botton in GUI for read x value, these are going to be appreciably different.
2)同样在第一次通信之后,服务器传递给客户端的值也会延迟,因此,例如,如果我同时向服务器发送x的请求并在GUI中推动该botton以读取x值,则这些值将是可观的不同。
This is the client script i use: 这是我使用的客户端脚本:
import time
import socket
class client_class:
def __init__(self, sock=None):
if sock is None:
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
else:
self.sock = sock
def connect(self,host,port):
self.sock.connect((host, port))
def invia(self,MSGLEN,msg):
totalsent = 0
if(len(msg)<MSGLEN):
while(len(msg)<MSGLEN):
msg=msg+'*'
while totalsent < MSGLEN:
sent = self.sock.send(msg[totalsent:].encode('ascii'))
if sent == 0:
raise RuntimeError
totalsent = totalsent + sent
def ricevi(self,MSGLEN):
msg = ''
while len(msg) < MSGLEN:
chunk = self.sock.recv(MSGLEN-len(msg)).decode('ascii')
if chunk == '':
raise RuntimeError
msg = msg + chunk
i=0
messaggio=''
while(i<MSGLEN):
if(msg[i]!='*'):
mess=msg[i]
else:
pass
messaggio=messaggio+mess
i+=1
return messaggio
client=mysocket()
ip='192.168.1.134'
port=8033
client.connect(ip,port)
while(True):
print("inserire comando da inviare (max 100 Bytes)")
msg=input().encode('ascii')
client.invia(100,msg)
print(client.ricevi(100).decode('ascii'))
Any help will be appreciate, thank you very much and sorry for bad english 任何帮助将不胜感激,非常感谢,英语不好
UPDATE UPDATE
I found that if i close socket on each communication, so for example everytime i need to send a message i open a client socket and close it after send it, could solve the problem, no error and no delay. 我发现,如果我在每次通信时都关闭套接字,那么例如每次我需要发送一条消息时,我打开一个客户端套接字并在发送后关闭它就可以解决问题,没有错误,没有延迟。 Can't explain me why, so if anyone could answer it will be appreciated.
无法解释我为什么,所以如果有人可以回答,将不胜感激。 Thank you very much
非常感谢你
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.