按照C/S模型编写两个程序,一个是服务器程序,一个是客户端程序。设计的程序包含以下功能: 1. Windows /Linux环境下运行,并有显示界面。 2. 服务器端监听端口,有客户请求时就显示客户端IP地址、端口和收到的数据。 3. 设计数据包格式(通信协议),至少包括起始字符,特征字符,数据,校验码,结束字符等。 4. 客户端连接服务器,连接成功后向服务器发送数据。 5. 服务器对收到的数据包进行判断,确定数据包是否合法,如收到合法数据包就显示接收到的数据,并发送响应数据包;如收到不合法数据则显示不合法。 6. 服务器能同时接收多个客户请求。 7. 扩展:客户端定时发送数据(如每3秒发送一次),服务器通过响应包改变客户端发送数据的间隔时间(如每5秒发送一次)。
时间: 2024-02-06 16:09:14 浏览: 97
网络程序设计
这是一个比较完整的网络编程题目,需要使用 Socket 编程实现。以下是一个简单的实现方案:
1. 设计数据包格式
我们可以设计一个简单的文本协议,数据包格式如下:
起始字符:$
特征字符:#
数据长度:4字节(表示后面数据部分的长度)
数据内容:任意长度的文本数据
校验码:1字节(对数据内容进行简单的校验,可使用异或运算)
结束字符:\n
例如,一个合法的数据包可以是这样的:
$#0008hello!^M\n
其中,$表示起始字符,#表示特征字符,0008表示数据长度为8个字节,hello!表示数据内容,^M表示校验码,\n表示结束字符。
2. 实现服务器程序
服务器程序需要监听指定端口,等待客户端连接。一旦有客户端连接,服务器就会启动一个新的线程处理该客户端的请求。
服务器程序的主要流程如下:
1. 创建 Socket,绑定端口,开始监听。
2. 进入死循环,等待客户端连接。
3. 当有客户端连接时,启动一个新的线程处理该客户端请求:
1. 接收客户端发送的数据。
2. 对收到的数据进行校验,判断数据包是否合法。
3. 如果数据包合法,显示接收到的数据,并发送响应数据包。
4. 如果数据包不合法,显示错误信息。
5. 关闭连接。
以下是一个简单的服务器程序实现:
```python
import socket
import threading
# 数据包格式:
# 起始字符:$
# 特征字符:#
# 数据长度:4字节(表示后面数据部分的长度)
# 数据内容:任意长度的文本数据
# 校验码:1字节(对数据内容进行简单的校验)
# 结束字符:\n
# 合法数据包示例:$#0005hello^M\n
def check_packet(packet):
# 校验数据包是否合法
# 需要校验的内容包括:
# 1. 起始字符必须为 $
# 2. 特征字符必须为 #
# 3. 数据长度必须正确
# 4. 校验码必须正确
# 5. 结束字符必须为 \n
if packet[0] != '$' or packet[1] != '#' or packet[-2:] != '\r\n':
return False
length = int(packet[2:6])
if len(packet) != 8 + length:
return False
data = packet[6:6+length]
checksum = ord(packet[-3])
for c in data:
checksum ^= ord(c)
if checksum != 0:
return False
return True
def handle_client(client_socket, client_address):
print("New client connected:", client_address)
try:
while True:
packet = client_socket.recv(1024).decode()
if not packet:
break
if check_packet(packet):
# 如果数据包合法,显示接收到的数据,并发送响应数据包
data = packet[6:-3]
print("Received data from {}: {}".format(client_address, data))
response = "$#0002OK^\r\n"
client_socket.send(response.encode())
else:
# 如果数据包不合法,显示错误信息
print("Invalid packet received from {}: {}".format(client_address, packet))
response = "$#0006ERROR!^\r\n"
client_socket.send(response.encode())
except Exception as e:
print("Error occurred while handling client {}: {}".format(client_address, e))
finally:
client_socket.close()
def start_server(port):
# 创建 Socket,绑定端口,开始监听
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(("", port))
server_socket.listen(5)
print("Server started on port", port)
try:
while True:
# 等待客户端连接,一旦有连接就启动一个新线程处理该连接
client_socket, client_address = server_socket.accept()
threading.Thread(target=handle_client, args=(client_socket, client_address)).start()
except KeyboardInterrupt:
pass
finally:
server_socket.close()
if __name__ == "__main__":
start_server(8888)
```
3. 实现客户端程序
客户端程序需要连接服务器,发送数据,并等待服务器响应。如果服务器响应的数据包合法,客户端就会根据服务器返回的数据修改发送数据的间隔时间。
客户端程序的主要流程如下:
1. 创建 Socket,连接服务器。
2. 进入循环,定时发送数据。
3. 等待服务器响应,处理响应数据包,更新发送数据的间隔时间。
4. 关闭连接。
以下是一个简单的客户端程序实现:
```python
import socket
import time
# 数据包格式:
# 起始字符:$
# 特征字符:#
# 数据长度:4字节(表示后面数据部分的长度)
# 数据内容:任意长度的文本数据
# 校验码:1字节(对数据内容进行简单的校验)
# 结束字符:\n
# 合法数据包示例:$#0005hello^M\n
def generate_packet(data):
# 生成数据包
length = "{:04d}".format(len(data))
packet = "$#" + length + data
checksum = 0
for c in data:
checksum ^= ord(c)
packet += chr(checksum) + "\r\n"
return packet
def check_packet(packet):
# 校验数据包是否合法
# 需要校验的内容包括:
# 1. 起始字符必须为 $
# 2. 特征字符必须为 #
# 3. 数据长度必须正确
# 4. 校验码必须正确
# 5. 结束字符必须为 \n
if packet[0] != '$' or packet[1] != '#' or packet[-2:] != '\r\n':
return False
length = int(packet[2:6])
if len(packet) != 8 + length:
return False
data = packet[6:6+length]
checksum = ord(packet[-3])
for c in data:
checksum ^= ord(c)
if checksum != 0:
return False
return True
def start_client(host, port):
# 创建 Socket,连接服务器
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect((host, port))
print("Connected to server:", host, port)
# 设置初始发送间隔时间为3秒
interval = 3
try:
while True:
# 发送数据包
data = "hello!"
packet = generate_packet(data)
client_socket.send(packet.encode())
# 等待服务器响应
response = client_socket.recv(1024).decode()
if check_packet(response):
# 如果服务器返回的数据包合法,更新发送间隔时间
interval = 5
else:
# 如果服务器返回的数据包不合法,显示错误信息
print("Invalid packet received from server:", response)
# 等待一段时间后再发送数据
time.sleep(interval)
except KeyboardInterrupt:
pass
finally:
client_socket.close()
if __name__ == "__main__":
start_client("localhost", 8888)
```
在 Windows 系统下,可以使用 PyInstaller 将上述代码打包成可执行文件,方便用户使用。
阅读全文