基于TCP协议的套接字编程(socket编程)
什么是Socket?
我们经常把Socket翻译为套字,Socket是在应用层和传输层之间的一个抽象层,它把TCP/IP层复杂的操作抽象为几个简单的借口供应用层调用已实现进程在网络中通信。
-
套接字的分类:
- AF_UNIX : 用在局域网中
- AF_INET : 用在互联网中
客户端和服务端该如何启动?
我们应该先启动服务端,服务端启动来之后,等待着客户端来连接,然后接收客户端发来的消息进行通信
TCP套接字模版
服务端
# 1.导入模块
import socket
# 2.实例化,
# 或者sever = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sever = socket.socket()
# 3.设定ip地址+端口号,得以元组的形式传入
sever.bind(('127.0.0.2', 8999))
# 4.监听,最多接收多少台客户端
sever.listen(5)
# 5.等待接收 数据+ip地址
sock, addr = sever.accept()
# 6.将数据取出来
date = sock.recv()
# 7.向客户端发送数据,必须是字节模式
sock.send(b'helloword')
# 8.关闭与客户端的连线
sock.close()
# 9.关闭服务器(类)
sever.close()
客户端
# 1.导入模块
import socket
# 2.实例化
client = socket.socket()
# 3.传入的ip地址+端口号,得以元组的形式传入
client.bind(('127.0.0.2', 8999))
# 4.向服务端传入数据,必须是字节
client.send(b'helloword')
# 5.接收服务器发来的信息
client.recv()
# 6.关闭与服务器的连线
client.close()
TCP循环通信
实现服务器可以重复通信、客户端也可以重复通信,不过不满足多用户通信
服务器
import socket
sever = socket.socket()
sever.bind(('127.0.0.2', 8999))
sever.listen(5)
while True:
# 如果一直没收到信息会一直卡在等待
sock, addr = sever.accept()
date = sock.recv()
sock.send(b'helloword')
sock.close()
sever.close()
服务端
import socket
client = socket.socket()
client.bind(('127.0.0.2', 8999))
while True:
# 循环向服务器发送信息
res = input('输入>>>')
client.send(res.encode('utf8'))
client.recv()
client.close()
基于UDP协议的套接字编程
服务端
import socket
# 数据协议 UDP
sever = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sever.bind(('127.0.0.2', 8999))
while True:
# client_addr:客户端地址:ip+port
sock, addr = sever.recvfrom(1024)
# 向客户端发送信息
sock.sendto(b'helloword')
sever.close()
客户端
import socket
client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
while True:
res = input('输入>>>')
# 向服务器发送信息
client.sendto(res.encode('utf8')), ('127.0.0.1', 8000)
# 接收服务端发来的信息
data, server_addr = client.recvfrom(1024)
client.close()
粘包现象
粘包就是当一方接收信息时,发送端发送的消息超过了接收方所接收的字节长度,接收方会接收相应的字节,当接收端再次接收信息时,不会接收新的信息,反而会按照次数接收第一次未接受完的信息
粘包现象:就是管道中的数据没有完全取出来
-
TCP的特性:流式协议
-
当客户端发送的数据量很小并且时间间隔很小的时候,
它会把数据打包成一个包一次性发送
struct模块
解决粘包现象