🌴 2022.6.10 下午 实验八

实验八 网络程序设计

题目

使用基于TCP或UDP套接字编写一个智能聊天机器人程序

问题分析

TCP工作需要建立连接、数据连接、断开连接三个步骤。利用socket模块,设计服务端与客户端,通过设置IP和端口号将二者连接。在服务端建立词库,客户端给服务端发送消息,服务端与词库做匹配后返回给客户端并输出

socket模块常用于TCP编程的方法:

socket.socket:创建套接字

serverSocket.bind((IP, Port)) :绑定套接字

connect(address):连接远程计算机

send(bytes[,flags]):发送数据

recv(bufsize[,flags]):接收数据

bind(address):绑定地址,通常用于服务端

listen(backlog):开始监听,等待客户端连接

accept():响应客户端的请求

代码

简易版

# server.py
'''先运行服务端再运行客户端'''
"""
@Author:张时贰
@Date:2022年06月15日
@CSDN:张时贰
@Blog:zhsher.cn
"""
import socket
serverSocket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) #创建套接字
serverSocket.bind(('127.0.0.1',12345)) #绑定套接字
print("在12345端口绑定UDP...")
answers = ["伽利略, 哥白尼","爱迪生, 特斯拉","诺贝尔, 门捷列夫"] #回答列表
i = 0
while True:
question,addr = serverSocket.recvfrom(1024) #接收客户端信息
print("客户端问:",question.decode()) #输出接收的问题
#发送数据给客户端
serverSocket.sendto(bytes("服务器答:" + answers[i],encoding='utf8'),addr)
i = i + 1
serverSocket.close() #关闭套接字
# client.py
"""
@Author:张时贰
@Date:2022年06月15日
@CSDN:张时贰
@Blog:zhsher.cn
"""
import socket
clientSocket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) #创建套接字对象
questions = ['世界上最伟大的天文学家是谁?','世界上最伟大的发明家是谁?',
'世界上最伟大的化学家是谁?'] #问题列表
#遍历发送列表questions中的问题
for question in questions:
#发送问题给服务器
clientSocket.sendto(bytes(question,encoding='utf8'),('127.0.0.1',12345))
print("客户端问:" + question) #输出发送的问题
answer,addr = clientSocket.recvfrom(1024) #接收服务器回答
print(str(answer.decode())) #输出回答
clientSocket.close() #关闭套接字

略加优化,可以粗略判断回复相近消息

# server.py
"""
@Author:张时贰
@Date:2022年06月08日
@CSDN:张时贰
@Blog:zhsher.cn
"""
'''优化非原创,链接:http://t.csdn.cn/DOI0V'''
'''先运行服务端代码,然后运行客户端'''

import socket
from os.path import commonprefix

# 建立聊天回复字典
words = {'What is your name': 'Zhangshier',
'how are you?': 'Fine,thank you!',
'how old are you?': '18 forever',
'bye': 'Bye!'}
# 服务端主机IP地址和端口号,空字符串表示本机任何可用IP地址
HOST = "192.168.43.214"
PORT = 50007
# 使用IPV4协议,使用tcp协议传输数据
s = socket.socket ( socket.AF_INET, socket.SOCK_STREAM )
# 绑定端口和端口号
s.bind ( (HOST, PORT) )
# 开始监听,规定最多支持1个客户端连接
s.listen ( 1 )
print ( '目前监听的端口号是:', PORT )
conn, addr = s.accept ()
print ( '目前连接的IP地址是:', addr )
# 开始聊天
while True:
# 最多可以接收1024比特大小的内容,并解码
data = conn.recv ( 1024 ).decode ()
# 如果是空,退出
if not data:
break
print ( '接收到的内容:', data )
# 尽可能猜测对方的意思
m = 0
key = ''
for k in words.keys ():
# 删除多余的空白字符
data = ' '.join ( data.split () )
# 与某个键非常接近,就直接返回
if len ( commonprefix ( [ k, data ] ) ) > len ( k )*0.7:
key = k
break
# 使用选择法,选择一个重合度较高的键
length = len ( set ( data.split () ) & set ( k.split () ) )
if length > m:
m = length
key = k
# 选择合适的信息进行回复
conn.sendall ( words.get ( key, 'Sorry,can\'t find your problem! ' ).encode () )
conn.close ()
# client.py
import socket
import sys

# 服务端主机IP地址和端口号 192.168.43.214
HOST = "192.168.43.214"
PORT = 50007
# 使用IPV4协议,使用tcp协议传输数据
s = socket.socket ( socket.AF_INET, socket.SOCK_STREAM )
try:
# 连接服务器
s.connect ( (HOST, PORT) )
except Exception as e:
print ( '找不到服务器,请稍后重试!' )
sys.exit ()
while True:
c = input ( '请输入你想发送的消息:' )
# 发送数据,使用UTF-8编码成字节码
s.sendall ( c.encode () )
# 从服务端接收数据,大小最多为1024比特
data = s.recv ( 1024 )
# 解码
data = data.decode ()
print ( '收到回复:', data )
if c.lower () == 'bye':
break
# 关闭连接
s.close ()

结果

Python实验22