python 可以使用 socket 模块进行网络通信。
在python开发文档中可以查询到有关该模块的参考 https://docs.python.org/zh-cn/3/library/socket.html?highlight=socket#module-socket
一、使用 socket.socket()函数创建套接字
socket(socket_family, socket_type, protocol=0)
‘’‘
socket_family 可选 AF_UNIX 或 AF_INET
# AF_UNIX用于同一台机器上的进程间通信
# AF_INET对于IPV4协议的TCP和UDP
socket_type 可选 SOCK_STREAM 或 SOCK_DGRAM
# SOCK_STREAM 流式套接字,即TCP
# SOCK_DGRAM 数据报套接字,即UDP
protocol 通常省略,默认为 0
‘’’
- 创建TCP/IP套接字
tcpSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- 创建 UDP/IP 套接字
udpSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
socket对象内置方法
名 称 | 描 述 |
---|---|
服务器套接字方法 | |
s.bind() | 将地址(主机名、端口号对)绑定到套接字上 |
s.listen() | 设置并启动 TCP 监听器 |
s.accept() | 被动接受 TCP 客户端连接,一直等待直到连接到达(阻塞) |
客户端套接字方法 | |
s.connect() | 主动发起 TCP 服务器连接 |
s.connect_ex() | connect()的扩展版本,此时会以错误码的形式返回问题,而不是抛出一个异常 |
普通的套接字方法 | |
s.recv() | 接收 TCP 消息 |
s.recv_into() (Python 2.5 中新增) | 接收 TCP 消息到指定的缓冲区 |
s.send() | 发送 TCP 消息 |
s.sendall() | 完整地发送 TCP 消息 |
s.recvfrom() | 接收 UDP 消息 |
s.recvfrom_into() (Python 2.5 中新增) | 接收 UDP 消息到指定的缓冲区 |
s.sendto() | 发送 UDP 消息 |
s.getpeername() | 连接到套接字( TCP)的远程地址 |
s.getsockname() | 当前套接字的地址 |
s.getsockopt() | 返回给定套接字选项的值 |
s.setsockopt() | 设置给定套接字选项的值 |
s.shutdown() | 关闭连接 |
s.close() | 关闭套接字 |
s.detach() (Python 3.2 中新增) | 在未关闭文件描述符的情况下关闭套接字,返回文件描述符 |
s.ioctl() (Python 2.6 中新增) | 控制套接字的模式(仅支持 Windows) POSIX 系统可以使用 functl 模块函数 |
面向阻塞的套接字方法 | |
s.setblocking() | 设置套接字的阻塞或非阻塞模式 |
s.settimeout() (Python 2.3 中新增) | 设置阻塞套接字操作的超时时间 |
s.gettimeout() (Python 2.3 中新增) | 获取阻塞套接字操作的超时时间 |
面向文件的套接字方法 | |
s.fileno() | 套接字的文件描述符 |
s.makefile() | 创建与套接字关联的文件对象 |
数据属性 | |
s.family (Python 2.5 中新增) | 套接字家族 |
s.type (Python 2.5 中新增) | 套接字类型 |
s.proto (Python 2.5 中新增) | 套接字协议 |
网络编程示例
1. TCP程序
1.1. 简单的服务器应答程序
功能:客户端连接服务端后,服务端发送“你好”到客户端,客户端接收数据并打印到屏幕上。
# server.py
from socket import socket
ss = socket() # 创建服务器套接字
ss.bind(("127.0.0.1",6000)) # 套接字与地址绑定
ss.listen(5) # 监听连接
while True: # 服务器无限循环
cs,c_addr = ss.accept() # 接受客户端连接
data = cs.send("你好..".encode("utf-8")) # 使用字节流传输数据
cs.close() # 关闭客户端套接字
ss.close() # 关闭服务器套接字
from socket import socket
s = socket() # 默认参数socket.AF_INET, socket.SOCK_STREAM
s.connect(("127.0.0.1",6000))
data = s.recv(1024) # 最大接收长度
print(data.decode("utf-8"))
s.close()
1.2. 服务器返回当前时间程序
import socket, time
serversocket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
serversocket.bind(('',8888)) # localhost/127.0.0.1
serversocket.listen(5)
while True:
(clientsocket, address) = serversocket.accept() #等待客户端连接
data = clientsocket.recv(4096) #接收姓名
print("打印: ", data.decode()) # 将字节流(bitys)转换为str
datetime = time.asctime()+'\n'
replay = 'Hello'.encode() + data; #回复:问候消息
replay += 'My time is '.encode() + datetime.encode()#回复:当前服务器时间
clientsocket.send(replay) # 发送消息
clientsocket.close()#关闭连接
import os
import sys
import socket
sock = socket.socket(socket.AF_INET,socket . SOCK_STREAM)
sock.connect((sys.argv[1],8888)) #服务器地址由命令行指定
sock.send( (os.getlogin() + '\n').encode()) #发送姓名
message = sock.recv(4096) #接收响应
print(message.decode()) #打印结果
sock.close()#关闭连接
# 编译命令 python client.py localhost
2.UDP程序
echo程序,客户端向服务器端发送数据,服务器将该数据再次发送会=回给客户端。
# ser.py
import socket
ss = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) # udp
ss.bind(("127.0.0.1", 6001)) # 绑定本地地址
while True:
data,addr = ss.recvfrom(1024)
print("from",addr,"recv:", data.decode("utf-8"))
ss.sendto(data, addr)
# cli.py
import socket
# udp
ss = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
ser_addr = ("127.0.0.1",6001) # 服务器地址
while True:
sendbuf = input("输入:")
if sendbuf == "exit":
break;
ss.sendto(sendbuf.encode("utf-8"), ser_addr)
data,_ = ss.recvfrom(1024)
print("recv:", data.decode("utf-8"))