套接字模块(python)可以工作,但不使用指定的端口号吗?

时间:2019-03-17 06:44:16

标签: python sockets network-programming port netstat

我正在使用Python 3.7中的socket模块(没关系,因为我尝试从不同的venv激活不同的Python版本)。

问题是我创建了一个TCP连接,侦听端口65432,这是我为此简单演示选择的任意数字。

server.py如下所示:

import socket

HOST = '127.0.0.1' # Standard loopback interface address (localhost)
PORT = 65432 # Non-privileged ports are > 1024

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.bind((HOST, PORT))
    s.listen() 
    conn, addr = s.accept() 
    with conn:
        print('Connected by', addr)
        while True:
            data = conn.recv(1024)
            if not data:
                break
            conn.sendall(data)

client.py相对简单,因为它与127.0.0.1:65432建立了联系。

import socket

HOST = '127.0.0.1' # The server's hostname or IP address
PORT = 65432 # Port used by the server

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.connect((HOST, PORT))
    # Send its message and then read the server's reply and prints it
    s.sendall(b'Hello, world')
    data = s.recv(1024)

print('Received', repr(data))

执行server.py打开端口65432进行侦听(在第一个控制台中),然后执行client.py发送简单的“ hello world”消息(在第二个控制台中)。这是打印到第一个控制台的内容:

Connected by ('127.0.0.1', 56051)

到目前为止,一切都很好。端口56051连接到端口65432,对吗?否

我执行netstat -am(命令工具实用程序以查看主机上套接字的状态)并发现了这一点:

Active Internet connections (including servers)
Proto Recv-Q Send-Q  Local Address          Foreign Address        (state)    
tcp4       0      0  127.0.0.1.51495        *.*                    LISTEN 

它使用端口51495代替了本地地址127.0.0.1.65432

再次进行验证检查,这次触发lsof -i -n

COMMAND     PID     FD   TYPE             DEVICE SIZE/OFF NODE NAME
Code\x20H 51214    37u  IPv4 0x1af15eb424ba89f3      0t0  TCP 127.0.0.1:51495 (LISTEN)

两个验证都确认正在使用端口51495,而不是我的server.pyclient.py脚本中指定的65432。有任何线索或提示吗?提前非常感谢!

2 个答案:

答案 0 :(得分:0)

65432是服务器套接字的端口号,而不是客户端套接字的端口号。由于客户端未附加任何特定端口号,因此每次您运行客户端代码时,都会为该端口动态分配端口号。 据我了解,您提到-

Connected by ('127.0.0.1', 56051)

显示在第一个控制台(即服务器控制台)上。因此,此端口号是客户端套接字的端口号。不是服务器套接字。

在服务器代码中,您正在使用s.accept(),此函数返回连接临时ID和发出请求的客户端地址。您尝试在代码中打印的内容相同。

答案 1 :(得分:0)

正如@ottomeister指出的那样,进程名称是第一个赠品。进程名称应该是Python,但是显示的是VS Code,这表示VS Code进程打开了端口51495,与我们的套接字模块代码无关。

上下文管理器的设置方式意味着连接将在执行最后一行(在本例中为socket.sendall())时关闭。因此服务器套接字不再处于活动状态。

我在客户端套接字连接后运行netstat,此时服务器端口已关闭。

当我在服务器端口打开时(在客户端套接字与之连接之前)监视端口状态时,请确保出现了足够的65432。在netstatlsofnmap中已确认。套接字连接成功后的简单打印语句还将确认服务器端口实际上正在使用指定的端口号65432。

给您带来的不便,我们深表歉意。再次感谢Ottomeister首先指出了这一点。