为什么要有套接字编程?
在上节课的学习中,我们学习了OSI七层协议,但是如果每次进行编程时我们都需要一层一层的将各种协议使用在我们的程序中,这样编写程序实在是太麻烦了,所以为了让程序的编写更加的简单,对OSI协议进行了封装,使我们只需要调用相应的接口就可以进行信息的接收与发送,而不用关注底层协议的实现
什么是套接字编程?
套接字是在应用层与底层之间的一个虚拟层,其中有一系列的接口,通过套接字的接口进行底层协议的设置,实际上就相当于把复杂的协议进行了隔离,只是留下接口进行设置,极大的降低了编程难度
套接字编程不知在python中使用,在其它语言中也是网络编程的实现方式,只不过调用的语法不太相同
如何使用套接字编程?
要进行套接字编程实现计算机间的信息传递至少需要两台电脑,根据C/S构架,需要编写一个客户端一个服务端
服务端的编写:
我们在进行服务端的编写时,可以参考我们使用手机的过程
import socket
import time
server = socket.socket(socket.AF_INET,socket.SOCK_STREAM) # 相当于买一台手机
server.bind(("127.0.0.1",8088)) # 为手机绑卡
server.listen(5) # 将手机开机进入随时可以监听电话的状态
while True:
conn,address = server.accept() # 等待电话的接入,获取来电显示
while True:
try:
res = conn.recv(1024) # 听对方说的话
print(res.decode("utf-8"))
if not res:
conn.close() # 挂断电话
break
# time.sleep(10)
conn.send(res.upper()) # 随着电话说话
except ConnectionResetError as e:
print(e)
conn.close()
break
print("开始等待下一个客户端的链接")
客户端的编写
import socket
client = socket.socket(socket.AF_INET,socket.SOCK_STREAM) # 创建一个socket对象
client.connect(("127.0.0.1",8088)) # 给服务器打电话
while True:
msg = input("请输入信息:")
if not msg:
continue
if msg in ["q"]:
client.close()
break
try:
client.send(msg.encode("utf-8"))
msg = client.recv(1024)
print(msg)
except ConnectionResetError as e:
print(e)
client.close()
break
在进行通讯时容易出现的问题
非正常退出的问题
当客户端进行非正常退出时:
当我们的客户端与服务端进行通讯时,客户端经常会非正常退出,此时服务端再对客户端发送数据或者接受客户端的请求服务端就会报错而导致服务器停止运行,这种事情时万万不能发生的,所以要尽量避免发生这种情况,我们需要在服务端使用异常处理机制进行处理,在检测到异常后主动与客户端断开连接。
当服务器非正常退出时:
当客户端与服务端进行通讯时,如果服务器非正常退出,此时再对服务器发送信息就会在客户端报错,导致客户端停止运行,此时也需要在客户端使用异常处理机制,在检测到异常后直接断开与服务器的链接
正常退出情况
当客户端正常退出时:
在客户端正常退出时会向服务器发送一条信息,此条信息会在服务器端显示为空字符串,此时我们只需要对接收的字符串进行判断就可以,当字符串为空时就断开与客户端的链接
当服务器进行正常退出时:
当服务器进行正常退出后,不会像客户端发送任何信息,我们只需要跟服务器异常退出时一样进行异常检测就可以,检测到异常后直接断开与服务器的链接即可
发送信息为空的情况
当客户端发送为空的字符串时,由于socket的优化机制,当检测到发送的消息为空时就默认不会进行发送,但是在客户端进行了发送,客户端进入recv等待的状态,服务器由于为检测到信息,所以还是在recv状态,此时就会进入死循环,所以我们需要对客户端发送的信息进行判断,如果是空时就直接进行循环,不进行发送
当服务器发送的字符串为空时,也会发生同样的情况,所以需要在服务端也进行判断。