1.客户端与服务端
计算机发展初期用户去取数据,直接就去主机拿,区分出客户端和服务端。
客户端:用户安装的软件。
服务端:统一管理数据库主机中的软件,再后来服务端外加了业务逻辑。
服务器:运行服务端的计算机被称为服务器。
(client)客户端:响应服务器向客户提供本地服务的程序。
(server)服务端: 对客户端机器提供数据服务程序。
1.1常用的两种架构
1. cs架构 client server 客户端-服务器模式。
2. bs架构 browser server 浏览器-服务器模式。
cs 架构要求
1.用户操作系统安装客户端,产商操作系统部署服务端。
2.每个用户需要独立安装软件,服务端升级也要每个用户升级客户端。
2.socket层
socket层:应用层于TCP/IP协议通信的中间抽象出来的一组接口,这个接口称为抽象层。
socket = ip + port。
ip 标识互联网中主机位置。
port 标识主机上的一个应用程序。
ip地址是配置到网卡上的,而port书应用程序开启的,ip与port的绑定标识了互联网中独一无二的一个应用程序。
3.套接字的工作流程
3.1 套接字方法
.bind() 绑定(主机,端口号)到套接字。
.listen() 开启TCP监听。
.accept() 被动接受TCP客户端的连接,为阻塞态,等待链接的到来,。返回一个对应此处连接的套接字。
客服端套接字方法
.connect() 主动初始化TCP服务器连接
公用方法
.recv() 接收TCP数据。
.send() 发送TCP数据,本质就是循环调用send在等待发送数据大于已端缓存区剩余空间时,数据不会丢失,循环调用send知道发送完。
.close() 关闭套接字。
4.基于TCP协议通信
TCP是基于链接的,必须先启动服务端,然后再启动客户端去链接服务器。
4.1服务端
import socket
server = socket.socket()
server.bind(('127.1.1.1', 8900))
server.listen(5)
sock, addr = server.accept()
date = sock.recv(1024)
print(date)
sock.send(date.upper())
sock.close()
server.close()
4.2客户端
import socket
client = socket.socket()
client.connect(('127.1.1.1', 8900))
client.send(b'hello')
date = client.recv(1024)
print(date)
client.close()
5.连接循环与通行循环
import socket
server = socket.socket()
server.bind(('127.1.1.1', 8900))
server.listen(5)
while True:
print('正常监听:')
sock, addr = server.accept()
while True:
date = sock.recv(1024)
if len(date) == 0:
break
print('收到消息:%s' % date.decode('utf-8'))
in_msg = input('回复消息:')
sock.send(in_msg.encode('utf-8'))
sock.close()
server.close()
正常监听:
收到消息:钱准备好了,货呢?
回复消息:货也准备好了,请验货!
收到消息:有内鬼快跑!
回复消息:我操!
import socket
client = socket.socket()
client.connect(('127.1.1.1', 8900))
while True:
in_msg = input('发送消息:')
client.send(in_msg.encode('utf-8'))
date = client.recv(1024)
print('收到消息:%s' % date.decode('utf-8'))
is_ok = input('按下*断开通信:')
if is_ok == '*':
break
client.close()
发送消息:钱准备好了,货呢?
收到消息:货也准备好了,请验货!
按下*断开通信:
发送消息:有内鬼快跑!
收到消息:我操!
按下*断开通信:*
5.1断开客户端问题
服务端在与客服端正常通信中,如果客服端正常断开,服务端会一直接到空数据包。
加上一个判断语句,如果收到空的数据包就表示客户端断开了,则使用break退出通信循环。
还有一种情况是服端非正常断开,客户端会报错。
ConnectionResetError: [WinError 10054] 远程主机强迫关闭了一个现有的连接。
import socket
server = socket.socket()
server.bind(('127.1.1.1', 8900))
server.listen(5)
while True:
print('正常监听:')
sock, addr = server.accept()
while True:
try:
date = sock.recv(1024)
if len(date) == 0:
break
print('收到消息:%s' % date.decode('utf-8'))
in_msg = input('回复消息:')
sock.send(in_msg.encode('utf-8'))
except ConnectionResetError:
print('远程主机强迫关闭了')
break
sock.close()
server.close()
6.UDP通信流程
6.1参数和方法
udp协议是无连接的,先启动谁都没问题。
参数 (type=socket.SOCK_DGRAM),设置通信UDP协议。
设置客户务端的socket 参数 (socket.AF_INET, socket.SOCK_DGRAM),设置通信UDP协议。
.recvfrom() 接收UDP数据。
.sendto() 发送UDP数据。
6.2 UDP服务端
import socket
server = socket.socket(type=socket.SOCK_DGRAM)
server.bind(('127.0.0.1', 8090))
date, client_addr = server.recvfrom(1024)
print(date)
print(client_addr)
server.sendto(date.upper(), client_addr)
server.clase()
6.3 UDP客户端
import socket
client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
msg =input('输入:').strip()
client.sendto(msg.encode('utf-8'), ('127.0.0.1', 8090))
date, sever_addr = client.recvfrom(1024)
print(date)
client.close()
6.4 循环通信
import socket
server = socket.socket(type=socket.SOCK_DGRAM)
server.bind(('127.0.0.1', 8090))
while True:
date, client_addr = server.recvfrom(1024)
print(date)
print(client_addr)
server.sendto(date.upper(), client_addr)
server.clase()
import socket
client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
while True:
msg =input('输入:').strip()
client.sendto(msg.encode('utf-8'), ('127.0.0.1', 8090))
date, sever_addr = client.recvfrom(1024)
print(date)
client.close()
clase()
import socket
client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
while True:
msg =input('输入:').strip()
client.sendto(msg.encode('utf-8'), ('127.0.0.1', 8090))
date, sever_addr = client.recvfrom(1024)
print(date)
client.close()
|