web-dev-qa-db-ja.com

pythonソケットを使用した2台のコンピューター間の通信

私はこれらの2つのプログラムを使用して、2台のコンピューター間で通信しています。1台はSSH接続されており、どちらの側にも何も返しません。何も送信せずに実行するだけです

クライアント

import sys
from socket import socket, AF_INET, SOCK_DGRAM

SERVER_IP   = '127.0.0.1'
PORT_NUMBER = 5000
SIZE = 1024
print ("Test client sending packets to IP {0}, via port {1}\n".format(SERVER_IP, PORT_NUMBER))

mySocket = socket( AF_INET, SOCK_DGRAM )

while True:
        mySocket.sendto('cool',(SERVER_IP,PORT_NUMBER))
sys.exit()

サーバ

from socket import socket, gethostbyname, AF_INET, SOCK_DGRAM
import sys
PORT_NUMBER = 5000
SIZE = 1024

hostName = gethostbyname( '0.0.0.0' )

mySocket = socket( AF_INET, SOCK_DGRAM )
mySocket.bind( (hostName, PORT_NUMBER) )

print ("Test server listening on port {0}\n".format(PORT_NUMBER))

while True:
        (data,addr) = mySocket.recvfrom(SIZE)
        print data
sys.ext()

何が間違っているのでしょうか?

6
GreatGather

問題はクライアントのアドレスにあります:

SERVER_IP   = '127.0.0.1'

サーバーが別のIPにあるときに、ローカルマシンに接続してデータを送信しています。サーバーのIPまたはホスト名のいずれかに接続する必要があります。

これを確認するには、クライアントを最初に接続します(接続できない場合は失敗します)。

...

import time

mySocket = socket( AF_INET, SOCK_DGRAM )
mySocket.connect((SERVER_IP,PORT_NUMBER))

while True:
        mySocket.send('cool')
        time.sleep(.5)

コメントからの更新

Wi-Fi接続を使用しているため、これらのマシンは両方ともローカルネットワーク上にあることを意味します。サーバーをターゲットとして指定するには、サーバーのLANIPアドレスを見つける必要があります。

IPを見つけるためのコマンドラインアプローチ

  • OSX/Linux:ifconfig
  • ウィンドウズ: ipconfig /all
8
jdi

このプログラムは、クライアントから「小文字の文字列」を送信し、サーバーから「大文字」を取得するために使用されます

サーバ側

import socket

def Main():

    Host = '192.168.0.12' #Server ip
    port = 4000

    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    s.bind((Host, port))

    print("Server Started")
    while True:
        data, addr = s.recvfrom(1024)
        data = data.decode('utf-8')
        print("Message from: " + str(addr))
        print("From connected user: " + data)
        data = data.upper()
        print("Sending: " + data)
        s.sendto(data.encode('utf-8'), addr)
    c.close()

if __name__=='__main__':
    Main()

クライアント側

import socket

def Main():

    Host='192.168.0.13' #client ip
    port = 4005

    server = ('192.168.0.12', 4000)

    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    s.bind((Host,port))

    message = input("-> ")
    while message !='q':
        s.sendto(message.encode('utf-8'), server)
        data, addr = s.recvfrom(1024)
        data = data.decode('utf-8')
        print("Received from server: " + data)
        message = input("-> ")
    s.close()

if __name__=='__main__':
    Main()
0
Barun Basnet

次のようなLANIPアドレスが表示されます。通常のWiFiルーターのデフォルトのローカルアドレスである192.168.1.102。たとえば、Windowsコマンドでipconfigを使用してプロンプトを表示すると次のように表示されます。

C:\Users\jackc>ipconfig

Windows IP Configuration

Wireless LAN adapter Wireless Network Connection 3:

   Media State . . . . . . . . . . . : Media disconnected
   Connection-specific DNS Suffix  . :

Wireless LAN adapter Wireless Network Connection:

   Connection-specific DNS Suffix  . :
   Link-local IPv6 Address . . . . . : fe80::ed97:91a4:9449:204b%13
   IPv4 Address. . . . . . . . . . . : 192.168.8.106
   Subnet Mask . . . . . . . . . . . : 255.255.255.0
   Default Gateway . . . . . . . . . : 192.168.8.1

私は私のために働く次のテストコードを試しました。

クライアント:

#!/usr/bin/env python3

import sys
from socket import socket, AF_INET, SOCK_DGRAM

SERVER_IP   = '192.168.8.102'
PORT_NUMBER = 5000
SIZE = 1024
print ("Test client sending packets to IP {0}, via port {1}\n".format(SERVER_IP, PORT_NUMBER))

mySocket = socket( AF_INET, SOCK_DGRAM )
myMessage = "Hello!"
myMessage1 = ""
i = 0
while i < 10:
    mySocket.sendto(myMessage.encode('utf-8'),(SERVER_IP,PORT_NUMBER))
    i = i + 1

mySocket.sendto(myMessage1.encode('utf-8'),(SERVER_IP,PORT_NUMBER))

sys.exit()

サーバ:

#!/usr/bin/env python3

from socket import socket, gethostbyname, AF_INET, SOCK_DGRAM
import sys
PORT_NUMBER = 5000
SIZE = 1024

hostName = gethostbyname( '0.0.0.0' )

mySocket = socket( AF_INET, SOCK_DGRAM )
mySocket.bind( (hostName, PORT_NUMBER) )

print ("Test server listening on port {0}\n".format(PORT_NUMBER))

while True:
    (data,addr) = mySocket.recvfrom(SIZE)
    print data
sys.exit()
0
Jackcc

SERVER_IPを実サーバーのアドレスに変更してもこれが機能しない場合は、サーバーのファイアウォールがポート5000でUDPのトラフィックを受け入れるかどうかを確認してください。

サーバーがLinuxマシンの場合、iptables-Lはファイアウォールルールを表示します。 iptables -Fはすべて(!)のファイアウォールルールを削除するので、それが役立つかどうかをテストできます。これは永続的な再起動ではありません。

0
Andre Blum

任意のクライアントに接続するには、ソケットをsocket.gethostname()にバインドする必要があります。これは私が成功して使用しているものであるか、空の文字列_""_を使用します

サーバーコードに関して:ソケットが外の世界に見えるようにsocket.gethostname()を使用しました。使用した場合

_s.bind(('localhost', 80)) 
_

または

_s.bind(('127.0.0.1', 80)) 
_

まだ「サーバー」ソケットがありますが、同じマシン内でのみ表示されるソケットです。 s.bind(('', 80))は、マシンがたまたま持っている任意のアドレスからソケットに到達できることを指定します。

ソース

0