NSt*_*enH 4 python sockets port
我正在尝试学习 python 套接字,但对网站上的示例代码的结果感到非常困惑(在此处找到)。
我所做的唯一修改是用socket.gethostname()我的服务器的本地 IP 替换服务器中的内容,以允许我在两台计算机上运行它。
当我连接时,尝试连接端口 12345(如示例所示),我得到以下输出:
Got connection from ('10.0.1.10', 37492)
这让我相信它正在连接端口 37492。我希望它连接到我告诉它的端口,这样我就可以进行端口转发。我是否误解了,或者是否有额外的命令来指定它。
编辑:我正在上传我的代码:
客户端.py
#!/usr/bin/python # This is client.py file
import socket # Import socket module
s = socket.socket() # Create a socket object
host = socket.gethostname() # Get local machine name
port = 12345 # Reserve a port for your service.
s.connect(("10.0.1.42", port))
print s.recv(1024)
s.close # Close the socket when done
Run Code Online (Sandbox Code Playgroud)
服务器.py
import socket
s = socket.socket() # Create a socket object
host = "10.0.1.42" # Get local machine name
port = 12345 # Reserve a port for your service.
s.bind((host, port)) # Bind to the port
s.listen(5) # Now wait for client connection.
while True:
c, addr = s.accept() # Establish connection with client.
print 'Got connection from', addr
c.send('Thank you for connecting')
c.close() # Close the connection
Run Code Online (Sandbox Code Playgroud)
您已经达到了网络生活中需要了解协议多路复用的阶段。对你有好处。
想想 TCP/IP 堆栈。应用程序通过将应用程序层数据传递到传输(端到端)层来与远程应用程序进行通信,传输层将其传递到网络层(网际层),网络层尝试(但不保证)数据包到达 IP 目标主机通过协作路由器确定的一系列跃点,这些路由器通过与连接的路由器通信来动态更新其路由表。每个路由器会话都经过某种物理传输(ISDN、以太网、PPP - 在 TCP/IP 中,创建数据包和传输适当比特流的任务被视为单个“子网”层,但这最终分为两个当 DHCP 等协议需要区分 OSI 物理层(第 1 层)和数据链路层(第 2 层)时。
当设计 TCP 和 UDP 时,设计者设想每个服务器都会侦听特定端口。这通常具有固有的限制,即端口只能处理服务协议的一种版本(尽管像 HTTP 这样的协议会注意向后兼容,以便旧服务器/客户端通常可以与新服务器/客户端进行互操作)。通常有一个名为 portmapper 的服务运行在端口 111 上,该服务允许服务器注册它们正在运行的端口号,并且客户端可以通过服务(程序)编号和协议版本查询注册的服务器。这是 Sun 设计的 RPC 协议的一部分,旨在将侦听端口的范围扩展到标准预先分配的端口之外。由于预分配的端口编号为 1 到 1023,并且这些端口通常(在合理的操作系统上)需要高级别特权,因此 RPC 还启用非特权服务器进程,并允许服务器响应多个版本NFS 等网络应用协议。
无论服务器端如何工作,事实仍然是网络层必须有某种方式来决定将特定数据包传递到哪个 TCP 连接(或 UDP 侦听器)。对于传输层也是如此(我在这里只考虑 TCP,因为它是面向连接的 - UDP 类似,但不介意丢失数据包)。假设我是一个服务器,我从同一台机器上的两个不同的客户端进程获得两个连接。如果客户端使用相同协议的相同版本,或者服务仅侦听单个端口,则目标(IP 地址、端口号)将相同。
服务器的网络层查看传入的 IP 数据报并发现它被寻址到特定的服务器端口。因此,它将其传递给传输层(网络层之上的层)中的该端口。服务器作为一个流行的目的地,可能有来自同一台机器上不同的不同客户端进程的多个连接。这就是临时端口的神奇之处。
当客户端请求用于连接到服务的端口时,TCP 层保证该机器上的其他进程(从技术上讲,该接口,因为不同的接口具有唯一的 IP 地址,但这是一个细节)不会被分配相同的端口编号,而客户端进程继续使用它。
因此协议复用和解复用依赖于五个信息:
(发送方IP、发送方端口、协议、接收方IP、接收方端口)
协议是 IP 标头中的一个字段,源 IP 地址和目标 IP 地址也是如此。发送和接收端口号位于传输层段标头中。
当传入数据包到达时,来自同一客户端(端点)的不同临时端口的唯一性保证允许传输层区分从相同客户端 IP 地址和端口到同一服务器 IP 地址的不同连接(解复用的最坏情况)通过其源 IP 地址和端口。包含(传输)协议是为了确保 TCP 和 UDP 流量不会混淆。TCP/UDP 对临时端口唯一性的限制保证任何服务器只能接收来自特定组合的一个连接(IP address, port number),这使得来自同一台计算机的连接能够被多路分解为与不同来源相对应的单独流。
在 Python 中,当您将套接字连接到远程端点时,socket.accept()调用将返回远程端点的(IP 地址、端口号)对。您可以使用它来发现谁在与您通信,但如果您只想顶嘴,则只需使用write()套接字即可。