Python:局域网下socket无法工作

0 投票
2 回答
8154 浏览
提问于 2025-04-17 20:11

我最近刚从假期回来,发现我的基本 Python 2 套接字服务器现在无法在局域网内与客户端通信。服务器在我的 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 测试

    a. 我能从我的 Mac 终端 ping 到树莓派:

    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. 但是我的树莓派找不到 Mac 作为主机。我会想办法解决这个问题。

    c. 我的 PC 能 ping 到我的 Mac,我的 Mac 也能 ping 到我的 PC。

  2. 防火墙

我的 Mac 防火墙是关闭的。我会去 [树莓派 Stackexchange 网站] 查看树莓派是否有防火墙。

我会在测试我的 Windows 机器后再添加更多信息。

2 个回答

0

你的代码运行得很好,不过我做了一些小的修改,并在代码里加了注释来解释这些修改:

服务器端代码:

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

上面的代码对我来说运行得很好,我相信对你也会一样,因为我也遇到过同样的问题。我在代码里找出的错误都在注释里,你可以看看。

祝好……!

0

在我的电脑上同时运行这两个脚本,它们能够成功连接和通信。你现在遇到的是网络问题,这个问题应该比较容易排查。

  1. 绑定错误。 在服务器上,打印出你得到的HOST。如果服务器有多个IP地址,可能你绑定到了错误的那个。你也可以把它改成'0.0.0.0'(只在服务器端),看看这样是否能解决问题。

  2. 防火墙。 任一方可能在操作系统层面上阻止了TCP通信。你可以使用Wireshark在Windows上进行调试,或者在Unix上使用tcpdump。启动抓包,运行你的代码,看看哪里出错了。你很可能会看到客户端发送了一个SYN包,但服务器没有回应SYN|ACK包。如果你看到SYN包到达了服务器,尝试完全关闭服务器的防火墙再试一次。如果没有到达,那可能是客户端被禁止了外发通信(这种情况不太常见),你需要关闭客户端的防火墙。

  3. 端口被占用。 尝试去掉SO_REUSEADDR选项进行调试,看看是否有变化。

  4. 异常处理。 确保你没有忽略任何来自套接字的异常信息。

撰写回答