2017-01-07 5 views
0

TCP通信のスキルを向上させるためにコーディングしていたときに見つけた問題について質問したいと思います。基本的に私は最初にソケットとサーバー/クライアントソケットと通信を開く方法について学びます。だから私は、サーバーとクライアントのための1のための1つのクラスを書いている私はそれをテストし、私は彼らが私は気に何のための非常に細かい仕事が見つかりました:これは、サーバーpython TCP通信スレッド、遅延、エラー

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 

であり、これはクライアントです:

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 

この時点では全く問題はありません。私がやろうとした次のステップは、いくつかの数学やGUI、あるいはその両方を実行しながら、クライアントとの通信のためにサーバーを稼働させ、例えば数学で動く情報を作成することでした。私はこれを行うために見つけた唯一の方法は、スレッドモジュールを使用しています。 私は2つの関数を書いています.1つはサーバ用、もう1つは数学用です(whileループではxの値を増やします)。次に、各関数をスレッドに渡します。 これは、サーバ機能(前定義されたものを使用するサーバクラス)である:

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) 

これは 'GO' という名前の数学関数です:

​​

は、最後に主な機能は次のとおりです。

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() 

機能を継続的に増やすx値、サーバー機能サーバーのリスニングを維持し、メインスレッドはユーザーがボトムボタンを押してx値を表示できるGUIを維持します。 サーバは、クライアントからのコマンドを3つだけ知っています。 1)クライアントにxを渡します。 2)クライアントを閉じます 3)サーバを閉じます これは未知のコマンドとして応答します。 何が起こるかは、コミュニケーションがうまくいかないことです。例えば、クライアント(以前に定義されたクライアントクラスを使用している他のマシン上で実行している)からサーバにX値を渡すように要求すると(その関数は常に増加しています)、間違ったものが2つ発生します。私は2回目にx値を求めるサーバの応答を未知のコマンドとして、3回目にx値の要求を送信して、それに値を与えます。次回は、未知のものとして答えるつもりですし、次に私に価値などを与えます。 2)最初の通信後も、サーバーがクライアントに渡す値は遅れます。たとえば、同時にxがサーバー要求に送信され、GUIのbottonをx値読み取りに押し込むと、これらの値は明らかに異なる。

これは私が使用するクライアントスクリプトです:どうもありがとうございました、すべてのヘルプは感謝されます

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')) 

との悪い英語

答えて

0

UPDATE

のため申し訳ありませんが、私は場合、私はソケットを閉じることがわかりました各通信では、毎回メッセージを送信する必要があるたびに、クライアントソケットを開いて送信してから問題を解決できるようになります。エラーも遅延もありません。 理由を説明できないので、誰かがそれに感謝することができれば。 ありがとうございました