【问题标题】:Communication between two computers using python socket使用python套接字在两台计算机之间进行通信
【发布时间】:2012-07-06 08:39:28
【问题描述】:

我正在使用这两个程序在我的两台计算机之间进行通信,其中一台是我通过 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()

我做错了什么?

【问题讨论】:

    标签: python sockets networking


    【解决方案1】:

    问题出在你客户的地址上:

    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)
    

    来自 cmets 的更新

    因为您使用的是 wifi 连接,这意味着这两台机器都在本地网络上。您需要找到服务器的 LAN ip 地址,将其指定为目标。

    命令行方法来查找您的 IP

    • OSX/Linux:ifconfig
    • Windows:ipconfig /all

    【讨论】:

    • 我使用了 whatismyip.com 的地址,结果相同
    • @user1340048:那是你的公共 IP。除非您已将路由器设置为将端口上的流量转发到您的服务器计算机,否则这对您没有多大好处。使用本地网络ips。这两台机器是否位于两个不同的网络位置?
    • 不,它们在同一个无线连接上。我在哪里可以找到正确的本地 ip?我曾尝试使用 SERVER_IP = ''
    • 那么您确实想使用本地网络 ips。这取决于您的操作系统。查看您的网络配置以找到您的 ip。通常在控制面板或命令行工具中
    • @user1340048:另外,设置 SERVER_IP="" 与 localhost 相同。由于它们在两台不同的机器上运行,因此您需要指定目标 IP。在 osx/linux 上,命令可以是:ifconfig en0。在 Windows 上可能是 ipconfig /all
    【解决方案2】:

    该程序用于从客户端发送“小写字母字符串”并从服务器获取“大写字母”

    服务器端

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

    【讨论】:

      【解决方案3】:

      如果将 SERVER_IP 更改为真实服务器的地址后仍无法正常工作,请检查服务器上的防火墙是否接受端口 5000 上的 UDP 流量。

      如果您的服务器是 linux 机器,iptables -L 会显示防火墙规则。 iptables -F 将删除所有(!)防火墙规则,因此您可以测试是否有帮助。这不是永久重启。

      【讨论】:

      • 不幸的是,它仍然无法正常工作,防火墙说它允许一切。
      【解决方案4】:

      您应该会看到如下所示的 LAN ip 地址:192.168.1.102,这是通常的 WiFi 路由器默认本地地址。例如,您将在 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()
      

      【讨论】:

        【解决方案5】:

        要连接到任意客户端,您必须将套接字绑定到 socket.gethostname() 这是我成功使用的或使用空字符串""

        关于服务器代码:我们使用了socket.gethostname(),以便外部世界可以看到套接字。如果我们使用了

        s.bind(('localhost', 80)) 
        

        s.bind(('127.0.0.1', 80)) 
        

        我们仍然有一个“服务器”套接字,但它只能在同一台机器中可见。 s.bind(('', 80)) 指定套接字可以通过机器碰巧拥有的任何地址访问。

        source

        【讨论】:

          最近更新 更多