私はこれらの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()
何が間違っているのでしょうか?
問題はクライアントのアドレスにあります:
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を見つけるためのコマンドラインアプローチ
ifconfig
ipconfig /all
このプログラムは、クライアントから「小文字の文字列」を送信し、サーバーから「大文字」を取得するために使用されます
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()
次のような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()
SERVER_IPを実サーバーのアドレスに変更してもこれが機能しない場合は、サーバーのファイアウォールがポート5000でUDPのトラフィックを受け入れるかどうかを確認してください。
サーバーがLinuxマシンの場合、iptables-Lはファイアウォールルールを表示します。 iptables -Fはすべて(!)のファイアウォールルールを削除するので、それが役立つかどうかをテストできます。これは永続的な再起動ではありません。
任意のクライアントに接続するには、ソケットをsocket.gethostname()
にバインドする必要があります。これは私が成功して使用しているものであるか、空の文字列_""
_を使用します
サーバーコードに関して:ソケットが外の世界に見えるようにsocket.gethostname()
を使用しました。使用した場合
_s.bind(('localhost', 80))
_
または
_s.bind(('127.0.0.1', 80))
_
まだ「サーバー」ソケットがありますが、同じマシン内でのみ表示されるソケットです。 s.bind(('', 80))
は、マシンがたまたま持っている任意のアドレスからソケットに到達できることを指定します。