在上一篇,我们介绍了Socket的简单应用https://editor.csdn.net/md/?articleId=132721864,这里我们将进行功能扩展,实现服务器端根据客户端的不同问题进行针对性的回答。本案例将使用以下几个知识点:
一, 字典:
字典(Dictionary)是Python中非常常用的数据类型之一,它提供了一系列的操作来管理和处理键值对数据。以下是字典常见的操作:
- 添加或更新键值对:可以使用赋值操作符
=
来添加或更新字典中的键值对。
my_dict = {} # 创建一个空字典
my_dict['key1'] = 'value1' # 添加键值对
my_dict['key2'] = 'value2' # 添加键值对
my_dict['key1'] = 'new value' # 更新键对应的值
- 获取值:通过键来获取字典中对应的值,可以使用索引操作符
[]
或者get()
方法。
value = my_dict['key1'] # 使用索引操作符获取值
value = my_dict.get('key1') # 使用 get() 方法获取值
- 删除键值对:可以使用
del
关键字来删除字典中的键值对。
del my_dict['key1'] # 删除指定键值对
my_dict.clear() # 清空字典,删除所有键值对
- 遍历字典:可以使用
for
循环来遍历字典的键或键值对。
for key in my_dict: # 遍历键
print(key)
for key, value in my_dict.items(): # 遍历键值对
print(key, value)
举个例子
language={'what is your name':'i am tom','how old are you':'22','see u':'see u','1+1':'2'}
for key in language:
print(key)
for key,v in language.items():
print(key)
print("--------")
print(v)
运行结果为:
5. 判断键是否存在:可以使用 in
关键字来检查键是否存在于字典中。
if 'key1' in my_dict:
print('Key exists')
- 获取键和值的列表:可以使用
keys()
、values()
和items()
方法来获取字典中键、值或键值对的列表。
keys = my_dict.keys() # 获取所有键的列表
values = my_dict.values() # 获取所有值的列表
items = my_dict.items() # 获取所有**键值对**的列表
- 字典长度:使用
len()
函数可以获取字典中键值对的数量。
length = len(my_dict) # 获取字典长度
这些是字典常见的操作,可以根据具体的需求使用适当的操作来管理和处理字典中的键值对数据。字典是一种非常灵活和强大的数据结构,可以有效地组织和操作键值对数据。
我们基于上一篇文章中设计的简单c/s应用中加入language
字典,用于存储一些预定义的问题和对应的回答。
在这个程序中,当客户端发送一个问题给服务器时,服务器会检查该问题是否存在于language
字典的键中。如果存在,服务器会将对应的回答发送回客户端。
举例来说,当客户端发送"what is your name"时,服务器会返回"i am tom";当客户端发送"how old are you"时,服务器会返回"22";当客户端发送"1+1"时,服务器会返回"2"。这样就实现了基本的问答功能。
需要注意的是,这个程序中的language
字典是预定义的,只包含了少数问题和回答。如果希望增加更多的问题和回答,可以向language
字典中添加新的键值对。
完整代码如下:
服务端程序S代码
import socket
language={'what is your name':'i am tom','how old are you':'22','see u':'see u','1+1':'2'}
host='0.0.0.0'
port=6667
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host,port))
s.listen(1)
print("listing at port 6666")
conn,addr=s.accept()
print('connect by :',addr)
while True:
data=conn.recv(1024)
if not data:
break
print('Received message:',data)
conn.sendall(language.get(data))
conn.close()
s.close()
客户端程序C如下:
# from ZMQ@cuc
# date 2/21/23
import socket
import sys
host='127.0.0.1'
port=6667
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
s.connect((host,port))
except Exception as e:
sys.exit()
print("connnecting at port 6666")
#print('connect by :',addr)
while True:
c=input("you say:")
s.sendall(c)
data=s.recv(1024)
print('received:',data)
if c.lower()=='bye':
break
s.close()
以上C/S两个程序运行后会出现错误,原因在哪里?
二,编码/解码
编码(是将字符转换为字节序列)
解码(将字节序列转换为字符)
字节序列(Byte sequence)是由一系列字节组成的数据序列。在计算机中,所有的数据都以字节的形式进行存储和传输。字节序列可以表示各种类型的数据,包括文本、图像、音频和视频等。
要将字节序列转换为字符,可以使用解码(decode)操作。解码是将字节序列转换为字符的过程。
在Python中,可以使用字符串的decode()
方法进行解码。该方法接受一个编码方式(encoding)作为参数,将字节序列解码为字符串。常见的编码方式包括UTF-8、ASCII、ISO-8859-1等。
以下是将字节序列转换为字符的示例代码:
byte_sequence = b'Hello, World!' # 字节序列
decoded_string = byte_sequence.decode('utf-8') # 解码为字符串
print(decoded_string) # 输出:Hello, World!
在上述示例中,byte_sequence
是字节序列,通过调用decode('utf-8')
方法将其解码为字符串decoded_string
。
在编程中,字节序列通常以二进制形式表示,每个字节由8个比特(bits)组成。字节序列可以通过编码(将字符转换为字节序列)和解码(将字节序列转换为字符)操作来实现对文本的处理。
字节序列在网络通信、文件传输、数据存储等方面起着重要的作用。在网络中,数据通过字节序列在不同计算机之间传输。
因此,上面的C/S需要进行编码和解码处理!
如果客户端提交的问题不存在于字典中,服务器该做如何处理呢,可以发送一个默认的回答"nothing"(代码如上图)