基于UDP或TCP的Socket通信 - Python网络编程

通过Python,可以便捷地进行基于UDP或TCP的Socket网络通信。

基于UDP或TCP的Socket通信 - Python网络编程

本文内容整理自 James F. Kurose, Keith W. Ross Computer Networking: A Top-Down Approach (sixth edition)

  • 原书内容是Python2的兼容代码,根据我的开发环境,做了少许修改以便兼容Python3。
  • 经测试在Python3.5环境下可顺利执行。

1 UDP

1.1 UDPClient.py

1
2
3
4
5
6
7
8
9
10
# coding: utf-8
from socket import *
serverName = 'www.heary.cn' # 目标域名或IP地址
serverPort = 12000 # 目标端口号
clientSocket = socket(AF_INET, SOCK_DGRAM) # AF_INET指示协议簇(AF, Address Family), (DGRAM, Datagram)
message = input('Input lowercase sentence:') # input返回str类型
clientSocket.sendto(message.encode(), (serverName, serverPort)) # bytes = str.encode()
modifiedMessage, serverAddress = clientSocket.recvfrom(2048) # serverAddress包含IP和port
print(modifiedMessage)
clientSocket.close() # 关闭socket,继而关闭进程

1.2 UDPServer.py

1
2
3
4
5
6
7
8
9
10
# coding: utf-8
from socket import *
serverPort = 12000
serverSocket = socket(AF_INET, SOCK_DGRAM) # 创建socket时,port是从1024~65535中自动分配的
serverSocket.bind(('', serverPort)) # 将该socket与指定port绑定,服务器端提供固定port以便访问
print("The server is ready to receive")
while True:
message, clientAddress = serverSocket.recvfrom(2048) # 取缓存长度2048作为输入
modifiedMessage = message.decode().upper() # str = bytes.decode()
serverSocket.sendto(modifiedMessage, clientAddress)

1.3 服务器端部署

测试需要,我在云服务器端通过screen创建一个新的screen socket:

1
screen -S UDPServer

在新的screen中,运行UDPServer.py:

1
python UDPServer.py

此时,服务器端的监听进程已经开始工作,通过netstat可以查看网络通信端口信息:

1
netstat -an | grep 12000

可以看到结果显示:

1
2
ubuntu@VM-49-193-ubuntu:~$ netstat -an | grep 12000
udp 0 0 0.0.0.0:12000 0.0.0.0:*
  • 本机本地IP的12000端口开启,为UDP协议。

2 TCP

2.1 TCPClient.py

1
2
3
4
5
6
7
8
9
10
11
# coding: utf-8
from socket import *
serverName = 'www.heary.cn'
serverPort = 12000
clientSocket = socket(AF_INET, SOCK_STREAM) # AF_INET指示底层使用IPv4, SOCK_STREAM指示TCP套接字
clientSocket.connect((serverName, serverPort)) # 执行三次握手,建立TCP连接
sentence = input('Input lowercase sentence:')
clientSocket.send(sentence.encode()) # TCP socket基于连接,且已连接至服务器,直接send即可
modifiedSentence = clientSocket.recv(1024)
print(modifiedSentence)
clientSocket.close()

2.2 TCPServer.py

1
2
3
4
5
6
7
8
9
10
11
12
13
# coding: utf-8
from socket import *
serverPort = 12000
serverSocket = socket(AF_INET, SOCK_STREAM)
serverSocket.bind(('', serverPort)) # 将该socket与指定port绑定,服务器端提供固定port以便访问
serverSocket.listen(1) # 定义TCP最大请求连接数为1 (该参数最小为1)
print("The server is ready to receive")
while True:
connectionSocket, addr = serverSocket.accept() # 用于请求建立TCP连接时,服务器段调用accept,即可完成三次握手协议,建立TCP通信Socket:connectionSocket
sentence = connectionSocket.recv(1024)
capitalizedSentence = sentence.decode().upper()
connectionSocket.send(capitalizedSentence.encode())
connectionSocket.close() # 通信完成后,通信连接关闭(但监听连接持续存在)

2.3 服务器端部署

操作内容同上1.3

补充:

1
2
ubuntu@VM-49-193-ubuntu:~$ netstat -an | grep 12000
tcp 0 0 0.0.0.0:12000 0.0.0.0:* LISTEN
  • TCPServer.py执行后,TCP监听进程启动。
1
2
ubuntu@VM-49-193-ubuntu:~$ netstat -an | grep 12000
tcp 0 0 10.105.49.193:12000 42.244.62.236:2538 TIME_WAIT
  • TCP连接关闭,会有一段TIME_WAIT,约几秒钟,过后再检索,会发现该端口已经释放。