2017-11-06 19 views
0

何らかの理由で、次の基本プログラムは、クライアントを2回目からサーバーに接続します。サーバーを再起動するたびに毎回。誰かがこの行動の理由とこの問題を解決する方法を説明できますか?おそらくasyncoreはサーバー側でのみ使用されるからでしょうか? (Windows 7、Python 3)ありがとうございました!Pythonクライアント・サーバー・アプリケーションが接続しない

Сlient:

import socket 
sock = socket.socket() 
host = 'localhost' 
port = 8081 
tempr = port 
sock.connect((host,port)) 

サーバー:

import asyncore 
import socket 
import time 

class EchoHandler(asyncore.dispatcher_with_send): 

def handle_read(self): 
    data = self.recv(1024) 

class EchoServer(asyncore.dispatcher): 
    def __init__(self, host, port): 
    asyncore.dispatcher.__init__(self) 
    self.create_socket(socket.AF_INET, socket.SOCK_STREAM) 
    self.set_reuse_addr() 
    self.bind((host, port)) 
    self.listen(2) 

    def handle_accept(self): 
    pair = self.accept() 
    if pair is not None: 
     sock, addr = pair 
     print ('Incoming connection from %s' % repr(addr)) 
     handler = EchoHandler(sock) 

def main(): 
    host = 'localhost' 
    port = 8081 
    server = EchoServer(host, port) 

    print ('Server %s running'% port) 
    asyncore.loop() 

if __name__ == '__main__': 
    main() 
+0

あなたはどのようなエラーが出るのですか? –

+0

エラーと例外はありませんが、関数handle_accept()はクライアントへの2回目の接続からのみ実行されます。 – Viktor

+0

私はドキュメントから離れて、 'asyncore'に慣れていませんが、' handle_except'で 'accept'を呼ぶべきではないと思います。サーバは、おそらく接続を受け入れた後にその関数を呼び出すため、冗長です。 –

答えて

0

socketの全体のポイントはsend()recv()にあるクライアントとサーバ間のデータを(受信)。サーバーに接続した後、サーバーにいくつかのデータ(空の文字列を送信する必要がある)を送信する必要があります。サーバーはクライアントにデータを返したり、接続を閉じることがあります。

my_client.py

import socket 

sock = socket.socket() 
sock.connect(('localhost', 8081)) 
sock.send(b'data from client') 
print(sock.recv(32)) 
sock.close() 

my_server.py

import asyncore 
import socket 
import time 


class EchoHandler(asyncore.dispatcher_with_send): 
    def handle_read(self): 
     data = self.recv(1024) 
     print('data from client', data) 
     self.send(b'data from server') 
     self.close() 


class EchoServer(asyncore.dispatcher): 
    def __init__(self, host, port): 
     asyncore.dispatcher.__init__(self) 
     self.create_socket(socket.AF_INET, socket.SOCK_STREAM) 
     self.set_reuse_addr() 
     self.bind((host, port)) 
     self.listen(2) 

    def handle_accept(self): 
     pair = self.accept() 
     if pair is not None: 
      sock, addr = pair 
      print('Incoming connection from %s' % repr(addr)) 
      handler = EchoHandler(sock) 


def main(): 
    host = 'localhost' 
    port = 8081 
    server = EchoServer(host, port) 

    print('Server %s running' % port) 
    asyncore.loop() 


if __name__ == '__main__': 
    main() 

更新:あなたはすべて読まなくても、サーバーでソケットをクローズしているためOSError: [WinError 10038]:あなたはエラーが出るん
クライアントからのデータ。クライアント側でも同じことが起こっています。
Pythonのドキュメントでは、これらがvery basicの例であることが明示されています。

すべてのデータが送信されることを確認するには、sendall()メソッドを使用してください。メソッドsend()はすべてのデータの送信を保証しません。

あなたはこのようなwhileループとソケットからデータを読み取る必要があります。

my_client.py

import socket 

sock = socket.socket() 
sock.connect(('localhost', 8081)) 
sock.sendall(b'data from client') 

chunk = b'' # socket.recv returns bytes 
data = b'' # defined before to avoid NameError 
while True: 
    chunk = sock.recv(32) 
    if chunk: 
     data += chunk 
    else: 
     break 

print(data) 
sock.close() 

my_server.py

import asyncore 
import socket 
import time 


class EchoHandler(asyncore.dispatcher_with_send): 
    def handle_read(self): 

     chunk = b'' # socket.recv returns bytes 
     data = b'' # defined before to avoid NameError 
     while True: 
      chunk = self.recv(1024) 
      if chunk: 
       data += chunk 
      else: 
       break 

     print('data from client', data) 
     self.sendall(b'data from server') 
     self.close() 


class EchoServer(asyncore.dispatcher): 
    def __init__(self, host, port): 
     asyncore.dispatcher.__init__(self) 
     self.create_socket(socket.AF_INET, socket.SOCK_STREAM) 
     self.set_reuse_addr() 
     self.bind((host, port)) 
     self.listen(2) 

    def handle_accept(self): 
     pair = self.accept() 
     if pair is not None: 
      sock, addr = pair 
      print('Incoming connection from %s' % repr(addr)) 
      handler = EchoHandler(sock) 


def main(): 
    host = 'localhost' 
    port = 8081 
    server = EchoServer(host, port) 

    print('Server %s running' % port) 
    asyncore.loop() 


if __name__ == '__main__': 
    main() 
+0

答えをありがとう!クライアントの2回目の再起動後(サーバーが実行中)、例外が発生します(:[WinError 10038] – Viktor

+0

@Viktor次回は完全なエラー(発生行を含む)を入力してください。あなたは答えを得るのに2週間かかりました。私は古い回答を自由時間でチェックできたことは幸運です!OSError:[WinError 10038]ソケットではないものに対して操作が試みられました。 –

関連する問題