【问题标题】:Python: Sockets not working over LANPython:套接字不能在 LAN 上工作
【发布时间】:2013-03-14 13:02:52
【问题描述】:

我最近从假期回来,我的基本 python 2 套接字服务器现在无法通过 LAN 与客户端通信。服务器在 Mac 上,客户端是我的树莓派或我的 windows 7 机器。我这里简化了服务端和客户端的代码举个例子:

服务器

import socket
from thread import *

HOST = socket.gethostname()

print HOST

PORT = input ("Enter the PORT number (1 - 10,000)")



s = socket.socket(socket.AF_INET, socket.SOCK_STREAM )
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
print "Socket Created"


s.bind((HOST, PORT))

print "Socket Bind Complete"

s.listen(10)
print "Socket now listening"


    #Sending message to connected client
    #This only takes strings (words


while True:
    #Wait to accept a connection - blocking call
    connection, addr = s.accept()
    print "Connection Established!"

    connection.send("Welcome to the server. Type something and hit enter\n")

    #loop so that function does not terminate and the thread does not end
    while True:

        #Receiving from client
        data = connection.recv(1024)
        if not data:
            break
        connection.sendall(data)
        print data
    connection.close()
s.close()

客户

import socket #for sockets
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print "Socket Created"

#Get host and port info to connect
host = raw_input("HOST >>>   ")
port = 2468
s.connect((host, port))


while True:   
    #Send some data to the remote server
    message = raw_input(">>>  ")

    #set the whole string
    s.sendall(message)


    reply = s.recv(1024)
    print reply

问题

这里发生了什么?我正在获取本地 IP,但脚本仍然无法通信。会不会是操作系统的问题?


更多信息

  1. ping

    一个。我能够从我的 Mac 终端 ping PI:

    PING raspberrypi (67.63.55.3): 56 data bytes
    64 bytes from 67.63.55.3: icmp_seq=0 ttl=240 time=17.434 ms
    64 bytes from 67.63.55.3: icmp_seq=1 ttl=240 time=18.180 ms
    64 bytes from 67.63.55.3: icmp_seq=2 ttl=240 time=22.046 ms
    64 bytes from 67.63.55.3: icmp_seq=3 ttl=240 time=25.124 ms
    64 bytes from 67.63.55.3: icmp_seq=4 ttl=240 time=31.773 ms
    

    b.我的 PI 无法找到作为主机的 Mac。我会看看我能做些什么来解决这个问题。

    c。我的电脑能够 PING 我的 mac。我的 Mac 能够 ping 我的电脑

  2. 防火墙

我的 Mac 的防火墙已关闭。我将在 [Raspberry Pi Stackexchange Site] 上查看 PI 是否有防火墙。

我会在测试我的 windows 机器后添加更多信息

【问题讨论】:

  • 你能ping通其他机器吗? SSH 他们?他们的 IP 地址是静态的还是动态的?
  • @jozzas 不确定 IP(我知道我的外部是动态的) Ping 信息已添加。
  • Linux下zuo maz如果不是超级用户,则禁止绑定低于1024的端口。

标签: python macos sockets python-2.7 raspberry-pi


【解决方案1】:

在本地运行这两个脚本,它们设法在我的机器上连接和通信。您正面临网络问题,应该很容易调试。

  1. 错误的绑定。 在服务器上,打印你得到的 HOST。如果服务器有多个 IP,您可能会尝试绑定错误的 IP。您也可以将其更改为“0.0.0.0”(仅在服务器端),看看是否可行。

  2. 防火墙。 任何一方都可能在操作系统级别阻止 tcp 通信。调试是通过 Windows 上的 Wireshark 和 unix 上的 tcpdump 完成的。开始嗅探,运行您的代码,看看出了什么问题。您很可能会看到客户端发送SYN 数据包,但服务器将无法使用SYN|ACK 数据包进行响应。如果您看到SYN 数据包到达服务器,请尝试完全关闭服务器的防火墙并重试。如果没有,则客户端被禁止传出通信(不太可能),您将需要关闭其防火墙。

  3. 正在使用的端口。 尝试删除 SO_REUSEADDR 进行调试,看看是否有变化。

  4. 例外情况。 确保不要忽略套接字中的任何异常。

【讨论】:

  • 感谢您的帮助。我尝试了您建议的所有方法,但仍然遇到问题。我的新信息在上面。
  • 你能发布你的 tcpdump 输出吗?
  • 嗯...那是什么?我会找到一种方法来做到这一点...您是否需要它用于我所有的计算机
【解决方案2】:

您的代码运行良好,不过我做了一些小的更正,并在代码中的 cmets 中进行了解释:

服务器:

import socket
from thread import *

# 1.Gets the local ip/ip over LAN.
HOST =socket.gethostbyname(socket.gethostname()) 

print HOST

# 2.Use port no. above 1800 so it does not interfere with ports already in use.
PORT =input ("Enter the PORT number (1 - 10,000)") 

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM )
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
print "Socket Created"
s.bind((HOST, PORT))
print "Socket Bind Complete"
s.listen(10)
print "Socket now listening"
while True:
    connection, addr = s.accept()
    print "Connection Established!"
    connection.send("Welcome to the server. Type something and hit enter\n")
    while True:
        data = connection.recv(1024)
        if not data:
            break
        connection.sendall(data)
        print data
        connection.close()
s.close()

客户:

import socket 
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print "Socket Created"
host = raw_input("HOST >>>   ")

# 3. Use the same port no. entered on server.py as the client binds to the 
#    same port
port = input ("Enter the PORT number (1 - 10,000)") 
s.connect((host, port))

while True:   
    message = raw_input(">>>  ")    
    s.sendall(message)
    reply = s.recv(1024)
    print reply

上面的代码对我来说很好用,我相信你也可以,因为我遇到了同样的麻烦。发现的bug我已经放在cmet里面的代码里面看看。

干杯....!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-16
    • 2020-08-14
    • 2010-10-16
    • 1970-01-01
    相关资源
    最近更新 更多