为了让两个程序通过网络进行通信,二者均必须使用socket套接字。
socket用于描述IP地址和端口,是一个通信链的句柄,可以用来实现不同虚拟机或不同计算机之间的通信。
使用socket模块中的socket函数:
s = socket.socket(AddressFamily,Type)
AddressFamily:可以选择 ① AF_INET(用于Internet进程间的通信)
② AF_UNIX(用于同一台机器进程间的通信)
Type:套接字的类型,可以是 ① SOCK_STREAM(流式套接字,主要用于TCP协议)
② SOCK_DGRAM(数据报套接字,主要用于UDP协议)
#创建TCP/IP套接字
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
#创建UDP/IP套接字
s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
创建完成后生成一个socket对象。
socket对象的内置方法:
函数 | 说明 |
---|---|
s.bind() | 绑定地址(host,por) 到套接字, 在AF_INET 下以元组(host,port) 的形式表示地址 |
s.listen() | 开始TCP监听。backlog指定在拒绝连接之前,操作系统可以挂起的最大连接数量。该值至少为1,大部分应用程序设为5就可以了 |
s.accept() | 被动接收TCP客户端连接,并且以阻塞方式等待连接的到来 |
s.connect() | 主动初始化TCP服务器连接,一般 address的格式为元组(host,port) ,如果连接出错,则返回socket.error错误 |
s.recv() | 接收TCP数据,数据以字符串形式返回,bufsize 指定要接收的最大数据量。flag提供有关消息的其他信息,通常可以忽略 |
s.send() | 发送TCP数据,将string中的数据发送到连接的套接字。返回值是要发送的字节数量,该数量可能小于string的字节大小 |
s.sendall() | 完整发送TCP数据。将string中的数据发送到连接的套接字,但在返回之前会尝试发送所有数据。成功则返回None,失败则抛出异常 |
s.recvfrom() | 接收UDP数据,与recv()类似,但返回值是(data,address)。其中data是包含接收数据的字符串,address 是发送数据的套接字地址 |
s.sendto() | 发送UDP数据,将数据发送到套接字,address是形式为(host,port)的元组,指定远程地址。返回值是发送的字节数 |
s.close() | 关闭套接字 |
创建TCP连接时,主动发起连接的叫客户端,被动响应连接的叫服务器。
2、1 创建TCP服务器
流程:
①使用socket创建一个套接字
②使用bind绑定ip和port
③使用listen使套接字变为可以被动连接
④使用accept等待客户端的连接
⑤使用recv/send接收发送数据
例:服务器向浏览器发送‘Hello World’
#使用socket模块,通过客户端浏览器(使用浏览器作为客户端)向本地服务器发
#起请求,服务器接到请求后,向浏览器发送‘Hello World’
import socket #导入socket模块
host = '127.0.0.1' #主机IP
port = 8000 #端口号
web = socket.socket() #创建socket对象
web.bind((host,port)) #绑定地址
web.listen(5) #设置最多连接数
print("服务器等待客户端连接...")
while True:
conn,addr = web.accept() #建立客户端连接
data = conn.recv(1024) #获取客户端请求数据
print(data)
conn.sendall(b'Hello World') #向客户端发送数据
conn.close() #关闭连接
打开浏览器输入:127.0.0.1:8000,成功连接服务器以后,浏览器显示:Hello World
2、2 创建TCP客户端
例:创建一个TCP客户端,通过该客户端向服务器发送和接收消息
import socket
host = '127.0.0.1'
port = 8000
s = socket.socket()
s.connect((host,port)) #主动初始化TCP服务器连接
send_data = input('请输出要发送的数据:')
s.send(send_data.encode()) #发送数据
recvdata = s.recv(1024).decode() #接收数据,最大接受1024个字节
print('接收的数据为:',recvdata)
s.close() #关闭套接字
打开两个cmd窗口,先运行服务器(2、1)的程序,再运行客户端(2、2)的程序,在客户端的窗口输入要发送的数据,服务器的窗口会接受数据,并向客户端发送 ‘Hello World’
2、3 执行TCP服务器和客户端
制作简易聊天窗口:
①创建一个server.py文件:
import socket
host = socket.gethostname() #获取主机地址
port = 12345 #设置端口号
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) #创建TCP/IP套接字
s.bind((host,port)) #绑定地址
s.listen(5) #设置最多连接数量
conn,addr = s.accept() #被动接收TCP客户端连接
print('已连接')
while True:
recv_data = conn.recv(1024).decode() #接收客户端数据
if recv_data:
print('接收到的内容:',recv_data)
send_data = input('输入的发送内容:')
conn.send(send_data.encode()) #发送数据
conn.close() #关闭客户端套接字
s.close() #关闭服务器套接字
②创建一个client.py文件:
import socket
host = socket.gethostname() #获取主机地址
port = 12345 #设置端口号
c = socket.socket(socket.AF_INET,socket.SOCK_STREAM) #创建TCP/IP套接字
c.connect((host,port)) #主动初始化TCP服务器连接
print('已连接')
send_data = ''
while True:
send_data = input('输入的发送内容:')
c.send(send_data.encode()) #发送数据
recv_data = c.recv(1024).decode() #接收数据
if recv_data:
print('接收到的内容:',recv_data)
c.close() #关闭套接字
打开两个cmd窗口,先运行server.py文件,后运行client.py文件,显示‘已连接’后,就可以开始发送数据了。
UDP是面向消息的协议,通信时不需要建立连接,数据的传输自然是不可靠的。
UDP和TCP类似,使用UDP的通信双方也分为客户端和服务器。
制作简易聊天窗口:
①创建一个udpserver.py文件:
import socket
host = socket.gethostname() #获取主机地址
port = 12345 #设置端口号
s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) #创建UDP套接字
s.bind((host,port)) #绑定地址
while True:
recv_data,addr = s.recvfrom(1024) #接收客户端数据,addr是发送数据的套接字地址
if recv_data:
print('接收到的内容:',recv_data.decode())
send_data = input('输入的发送内容:')
s.sendto(send_data.encode(),addr) #发送数据给客户端
s.close() #关闭套接字
②创建一个udpclient.py文件:
import socket
host = socket.gethostname() #获取主机地址
port = 12345 #设置端口号
c = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) #创建UDP套接字
while True:
send_data = input('输入的发送内容:')
c.sendto(send_data.encode(),(host,port)) #发送数据到服务器
recv_data,addr = c.recvfrom(1024) #接收服务器数据,addr是发送数据的套接字地址
if recv_data:
print('接收到的内容:',recv_data.decode())
c.close() #关闭套接字
如有错误请指出
参考文献《python从入门到精通》