智能问答机器人服务器与客户端
socket用于根据指定的地址族、数据类型和协议来分配一个套接口的描述字及其所用的资源。
服务端套接字函数
server.bind() 绑定(主机,端口号)到套接字
server.listen() 开始TCP监听
server.accept() 被动接受TCP客户的连接,(阻塞式)等待连接的到来。
server.close() 关闭服务器。
connect.close() 关闭链接
客户端
client.connect(ip地址,端口号) 连接服务器
Python通过两个标准库 _thread和 threading提供对线程的支持:
_thread:提供了低级别的、原始的线程以及简单的锁
threading:用于提供线程的相关操作,线程是应用程序中工作的最小单元。
threading模块提供的类:
Thread, Lock, Rlock, Condition,local等
threading 模块提供的其他方法:
threading.currentThread(): 返回当前的线程变量。
threading.enumerate(): 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。
threading.activeCount(): 返回正在运行的线程数量,len(threading.enumerate())有相同的结果。
除了使用方法外,线程模块threading同样提供了threading.Thread类来处理线程,提供了以下方法(主要):
run():用以表示线程的活动方法
start():用于启动线程的活动
join([time]):等待至线程终止,阻塞线程调用直至线程的join()方法被调用终止、正常退出或者抛出未处理的异常、可选的超时异常的发生
isAlive():返回线程是否是活动的
getName():返回线程名
setName():设置线程名
服务器端
具体代码如下:
import socket
import threading
#问题库
questionDict={'苹果':'水果','猪':'是一种动物','狗':'是人类的好朋友','你好':'你好','我爱你':'我也爱你',
'猫':'爱吃老鼠','香蕉':'是一种水果','你叫什么名字':'小李','你吃饭了吗':'没有,肚子好饿','去吃饭吧':'好的','再见':'拜拜'}
#智能问答机器人服务器
class RobotServer():
def __init__(self,ip='127.0.0.1',port=8080,connectSize=100):
'''
port:服务器的端口号
connectSize:默认的并发数量
'''
self.__ip = ip
self.__port = port
self.__connectSize=connectSize
pass
def startServer(self):
#服务器启动的主程序
server=socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 套接字类型AF_INET, socket.SOCK_STREAM tcp协议,基于流式的协议
server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) # 对socket的配置重用ip和端口号
server.bind((self.__ip,self.__port)) #绑定端口号,写哪个ip就要运行在哪台机器上
server.listen(self.__connectSize) #设置半连接池,最多可以连接多少个客户端
while True:
clientConn,clientAddr = server.accept() # 在这个位置进行等待,监听端口号
#定义独立线程,处理每个请求
wt=WorkThread(clientConn,clientAddr)
wt.start()
pass
class WorkThread(threading.Thread):
def __init__(self,connection,addr,bufferSize = 8096):
threading.Thread.__init__(self)
self.__connection=connection
self.__addr = addr
self.__bufferSize = bufferSize
def run(self):
receiveMsg=self.__connection.recv(self.__bufferSize) # 接受套接字的大小,怎么发就怎么收
receiveMsg = receiveMsg.decode('utf-8')
answer = ""
for temp in questionDict.keys():
if temp.count(receiveMsg) >0:
answer = questionDict[temp]
break
if not answer:
print("你在说啥?")
self.__connection.send(answer.encode("utf-8"))
self.__connection.close() # 断开连接
pass
if __name__=="__main__":
rs=RobotServer()
rs.startServer()
客户端
具体代码如下:
from socket import *
class RobotClient():
def __init__(self,ip='127.0.0.1',port=8080,bufferSize=8096):
self.__ip = ip
self.__port = port
self.__bufferSize=bufferSize
pass
def startSendMsg(self,msg):
client = socket(AF_INET,SOCK_STREAM) # 套接字类型AF_INET, socket.SOCK_STREAM tcp协议,基于流式的协议
client.connect((self.__ip,self.__port)) #连接ip地址以及port端口
client.send(msg.encode('utf-8')) # 收发消息一定要二进制,指定编码格式
receive = client.recv(self.__bufferSize) # 接受套接字的大小
print(receive.decode('utf-8'))
client.close()
pass
if __name__=="__main__":
rs=RobotClient()
while True:
msg=input("你来说我来答:")
rs.startSendMsg(msg)
if msg == "再见": #如果输入 再见,则退出
break
如有纰漏,请多指教