Python: 网络编程基础

Socket

为了让两个程序进行网络通信,二者均需要使用 socket 套接字。套接字用来描述 IP 地址和端口,是一个通信链的句柄。

在 Python 中使用 socket 模块的 socket 模块,语法格式

1
s=socket.socket(AddressFamily,Type)

该函数带有两个参数

  • Address Family: 可以选择 AF_INET (用于 Internet 进程间通信) 或者 AF_UNIX (用于同一台机器进程间通信)

  • Type: 套接字协议,可以是 SOCK_STREAM (流式套接字,主要用于 TCP 协议) 或者 SOCK_DGRAM (数据报套接字,主要用于 UDP 协议)

如创建 TCP / IP 套接字

1
tcpsocket=socket.socket(socket.AF_INET,socket.SOCK_STREAM)

创建 UDP / IP 套接字

1
udpSock=socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

socket 对象内置方法

方法 描述
s.bind() 绑定地址 (hos,port) 到套接字, 在 AF_INET 下元组 (host,port) 的形式表示地址
s.listen() 开始 TCP 监听。backlog 指定在拒绝连接之前,操作系统可以挂起的最大连接数量。最少为一
s.accept() 被动接收 TCP 客户端连接,(阻塞式) 等待连接的到来
s.connect() 主动初始化 TCP 服务连接,一般 address 的格式为元组 (hostname,port),如果连接出错,返回 socket.error 错误
s.recv() 接收 TCP 数据,以字符串形式返回。bufsize 指定要接收的最大数据量;flag 提供有关消息的其它信息,通常可以忽略。
s.send() 发送 TCP 数据,将 string 中的数据发送到连接的套接字,但在返回之前会尝试发送所有数量。成功返回 None, 失败抛出异常
s.sendall() 完整发送 TCP 数据,将 string 中的数据发送到连接的套接字,但在返回之前会尝试发送所有数量。成功返回 None, 失败抛出异常
s.recvfrom() 接收 UDP 数据,返回值为 (data,address) 元组,其中 data 是包含接收数据的字符串,address 是发送数据的套接字地址
s.sendto() 发送 UDP 数据,与 recv 类似,address 形式为 (ipaddr,port) 的元组,指定远程地址。返回值为发送的字节数
s.close() 关闭套接字

TCP 编程

创建 TCP 服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import socket  # 导入 socket 模块
s=socket.socket()
host = '0.0.0.0' # 获取本地主机名
port = 34222 # 设置端口
s.bind((host, port))
s.listen(2)
print("waiting for connection")
while True:
con,addr=s.accept()
data=con.recv(1024)
str1=str(data.decode())
print(data.decode())
str1="你发送了:"+str1+"\n"
con.sendall(str1.encode())
con.close()
print("endall")

创建 TCP 客户端

1
2
3
4
5
6
7
8
9
10
import socket
s = socket.socket()
host = '175.178.38.129'
port = 34222
s.connect((host, port))
send_data =input("输入:")
s.send(send_data.encode())
recvDATA=s.recv(1024).decode()
print(recvDATA)
s.close()

UDP 编程

UDP 服务器

1
2
3
4
5
6
7
8
import socket
s=socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind(('127.0.0.1',8888))
data,addr=s.recv(1024)
print("data: ",data)
str=input("input:")
s.sendall(str,addr)
s.close()

UDP 客户端

1
2
3
4
5
6
import socket
s=socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
data=input("input:")
s.sendall(data.encode(),('127.0.0.1',8888))
print(s.recv(1024).decode())
s.close()