1. 服务端流程
#1. 创建套接字
sockfd = socket.socket(socket_family=AF_INET,socket_type=SOCK_STREAM,proto=0)
#参数:socket_family 网络地址类型,AF_INET表示ipv4,默认ipv4
#socket_type 套接字类型,SOCK_STREAM(流式)默认是流式套接字,SOCK_DGRAM为(数据报)
#proto 通常为0,选择子协议
#返回值:套接字对象
#2.绑定地址
sockfd.bind(addr)
#功能:绑定本机地址,ifconfig查看,若127.0.0.1只能本机自己玩,若网络地址,别的主机也可以访问你的客户端
#参数:二元元组(ip,port),port自选
#3.设置监听
sockfd.listen(n)
#功能:将套接字设置为监听套接字,确定监听队列大小(这样套接字才能获取客户连接,才能进行三次握手)
#参数:监听队列大小,linux下,由操作系统决定, 应用层无法更改,连接的方式是采用队列的方式一个个连接
#4.等待处理客户端连接请求
connfd,addr = sockfd.accept()
#功能:阻塞等待处理客户端请求
#返回值:connfd 客户端连接套接字
#addr 连接的客户端地址
#5. 消息收发
data = connfd.recv(buffersize) #recv是读操作,将网络中的内容读下来(本质是从网络缓冲区中读取,当网络缓冲区为空时堵塞)
#功能:接收客户端消息
#参数:每次最多接收消息的大小
#返回值:接收到的内容
n = connfd.send(data) #send是写操作
#功能:发送消息
#参数:要发送的内容 byte格式
#返回值:发送的字节数
#当服务端和客户端收发消息时,客户端退出,服务端如果不做任何处理,会返回brokenpipeError错误,一般用当收到消息为空时,退出循环来处理
#6.关闭套接字
sockfd.close()
#功能:关闭套接字
2.客户端流程(只有相同类型的套接字才能进行通信)
#1. 创建套接字
#2. 请求连接
sockfd.connect(server_addr)
#功能:连接服务器
#参数:服务器地址,是个元组(ip,端口)
#3. 收发消息
#4. 关闭套接字
示例
#服务端流程
import socket
#创建tcp套接字对象
sockfd = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
#绑定地址
sockfd.bind(('ip',port))
#设置监听
sockfd.listen(5)
#循环等待处理多个客户端请求
while True:
print('Waiting for connect...')
#当服务端要退出时:按ctrl+c,此时会抛出异常:KeyboardInterrupt,优雅点,捕获掉
try:
connfd,addr = sockfd.accept()
print('Connect from',addr)
except KeyboardInterrupt:
print('Server exit')
break
#抛出其他异常时不管,继续执行
except Exception as e:
print(e)
continue
#循环收发一个连接进来的客户端的消息
while True:
data = confd.recv(1024)
print('Receive:',data.decode())
#和客户端约定好,当发来的Msg为Q时,退出
if not data:
break
n = connfd.send(b'Thanks')
print('Send %d bytes' %n) #打印出发送了多少个字节
#关闭为某个客户端服务的连接套接字
connfd.close() #负责消息收发
#关闭套接字
sockfd.close() #负责监听
#客户端流程
from socket import *
#创建套接字
sockfd = socket() #可以不写参数,因为默认是ipv4和流式套接字
#连接服务器
server_addr = ('ip,port) #服务器地址
sockfd.connect(server_addr)
#循环发收消息,先发后收
while True:
msg = input('Msg:')
#写退出条件
if not msg:
break
sockfd.send(msg.encode()) #字节串
data = sockfd.recv(1024)
print('From server:',data.decode()) #将接收到的消息打印
#关闭套接字
sockfd.close()