首页 > 解决方案 > socket.accept() in python; How to set client side for the connection port

问题描述

Instead on posting my mile long script here is a short example: I am creating a TCP/IP connection between two computers each running one of the following scripts:

server:

# server.py
import socket

s = socket.socket()
host = socket.gethostname()
port = 1234
s.bind((host, port))

s.listen(5)

while True:
    c, addr = s.accept()
    print 'Connection from', addr
    c.close()

Client:

#client.py
import socket

s = socket.socket()

host = socket.socket()
port = 1234

s.connect((host, port))
print s.recv(1024)

which gives me a ready out like:

Connection from ('19*.1**.0.**', 54451)
Connection from ('19*.1**.0.**', 54452)
Connection from ('19*.1**.0.**', 54453)
Connection from ('19*.1**.0.**', 54454)

What is controlling the creation of the 54451-54454 numbers? I understand what it is; the port number assigned to the client side connection. I just cant seem to figure out how to control the number, or at least the range its issued in.

Is this even possible? Any suggestions would help immensely. Thank you in advance.

标签: pythonpython-3.xpython-sockets

解决方案


通常,如果您自己没有这样做,您的操作系统或运行时系统会分配端口 ID。

特别是 TCP 每个连接有两个端口:源端口和目标端口,有时称为本地和远程。Usings.bind设置服务器上的本地端口,而不设置任何远程端口(这很有意义:还没有实际连接)。使用s.connect设置客户端上的远程(目标)端口,而不设置任何本地端口。

当您的客户端向服务器发送连接请求时,您的客户端需要一个本地端口。由于它还没有,操作系统或运行时系统会从可用端口 ID 池中选择一个。然后,它将该 ID 绑定到客户端的本地端 socket s,并发送一个请求(我假设这里是 192.168 RFC-1918 私有地址空间):

<local-addr=192.168.xxx.xxx, local-port=54451, remote-addr=S, remote-port=1234>

(其中 S 是服务器的 IP 地址)。

服务器看到传入的请求,创建一个的套接字:

<local-addr=S, local-port=1234, remote-addr=192.168.xxx.xxx, remote-port=54451>

如您所见,这是同一对 IPaddr+端口号,只是交换了。

套接字是s.accept服务器上返回的内容,如c.

如果你想在客户端分配你自己的本地端口,你也可以bind在调用之前调用那里connect

s.bind((0, port))

(零表示“未分配”,因此本地 IP 地址未设置。您可以设置特定的 IP 地址,如果您的主机是多宿主的,这很有用。)


推荐阅读