在上一篇中,其实我们实现的都是服务端和客户端只进行了一次交互,就中断了,而且只能完成一次的对话,这在实际的工作中,肯定是多次对话的,那么如何来实现呢,今天,我们稍微做了一些演示。
服务器可以链接多个设备
循环聊天
校验用户输入内容
基于这五个方面,我们去实现下服务端
import socket
#1.产生一个socket 对象并指定采用的通信版本和协议(tcp)
server = socket.socket() # 括号内不写参数,默认就是TCP
# 2.绑定一个固定的地址
server.bind(('127.0.0.1',8089)) # 本机的ipv4地址,端口号
# 3.设立半连接池
server.listen(5)
while True: #链接循环
# 4.等待有用户链接 三次握手
sock, addr = server.accept() # 有两个数据值返回 return sock, addr
# sock就是双向通道,addr就是客户端地址
while True:
try:
# 5.服务用户 等待客户端发消息
data=sock.recv(1024) #接受客户端发送过来的信息 1024字节
print('来自客户端的消息',data.decode('utf8'))
if len(data) == 0:
break
msg =input('给客户发送的消息:').strip()
if not msg:
print('不能输入为空')
continue
sock.send(msg.encode('utf8')) # 给客户端发送消息 必须是bytes类型
#6.关闭双向通道
except BlockingIOError:
break
客户端实现
import socket
# 1.生成socket对象指定类型和协议
client =socket.socket()
#2.通过服务端的地址链接服务端
client.connect(('127.0.0.1',8089))
# 3.直接给服务端发送消息
while True:
msg=input('向服务端发送的消息:').strip()
if len(msg) == 0:
print('输入不能为空')
continue
client.send(msg.encode('utf8'))
# 4.接受服务端发送过来的消息
data = client.recv(1024)
#5.打印消息
print(data.decode('utf8'))
测试下
可以看到可以正常的接送发送消息,到这里,实现了一个设备,稍微进行了优化,但是实际中,还是要去一个服务端,要处理多个客户端,那么如何去实现呢,其实可以分析,当一个链接进来,我们得代码是进入一个链接的接收回复,我们已经可以允许多个客户端链接,如何做可以实现呢,可以通过线程的方式去处理即可,即,启动线程去处理单个的客户端的请求即可,那么如何实现呢
import socket
# 1.产生一个socket 对象并指定采用的通信版本和协议(tcp)
import sys
from threading import Thread
def reuqets(sock):
while True:
try:
# sock就是双向通道,addr就是客户端地址
# 5.服务用户 等待客户端发消息
data = sock.recv(1024) # 接受客户端发送过来的信息 1024字节
print('来自客户端的消息', data.decode('utf8'))
if len(data) == 0:
break
msg = input('给客户发送的消息:').strip()
if not msg:
print('不能输入为空')
continue
sock.send(msg.encode('utf8')) # 给客户端发送消息 必须是bytes类型
# 6.关闭双向通道 四次挥手
except BlockingIOError:
break
server = socket.socket() # 括号内不写参数,默认就是TCP
# 2.绑定一个固定的地址(服务端必备的条件)
server.bind(('127.0.0.1', 8013)) # 本机的ipv4地址,端口号
# 3.设立半连接池(防止洪水攻击()
server.listen(5)
while True: # 链接循环
# 4.等待有用户链接 三次握手
try:
sock, addr = server.accept() # 有两个数据值返回 return sock, addr
print(addr)
except KeyboardInterrupt :
server.close()
sys.exit()
t=Thread(target=reuqets,args=(sock,))
t.start()
其实很简单,就是把之前的链接客户端后的接收给做成了一个线程处理的函数,这样,就实现了。那么可以去测试下,
服务端的日志:
客户端1:日志
客户端2日志
我们在启动后,关闭后,再次启动发现接口不能重复使用了,如何做呢?
server = socket.socket() # 括号内不写参数,默认就是TCP
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) #实现端口复用
在socket后面增加端口复用的配置就解决了上述的问题。
客户端的退出,我们选择msg消息输入exit就退出
增加判断
if msg=="exit":
client.send(msg.encode('utf8'))
break
到这里,socket相关的聊天呢,我们就实现到了多客户端链接,但是有一个问题,比如:我们如何给单独的一个客户端发送消息,如何吧消息发给其他用户,那么如何来实现呢?我们下次在分享。