公益基金会网站开发的背景,企业简介模板免费下载,wordpress php 中文分词 开源,修改wordpress的样式本篇文章是博主在人工智能、网络通讯等领域学习时#xff0c;用于个人学习、研究或者欣赏使用#xff0c;并基于博主对人工智能等领域的一些理解而记录的学习摘录和笔记#xff0c;若有不当和侵权之处#xff0c;指出后将会立即改正#xff0c;还望谅解。文章分类在Python… 本篇文章是博主在人工智能、网络通讯等领域学习时用于个人学习、研究或者欣赏使用并基于博主对人工智能等领域的一些理解而记录的学习摘录和笔记若有不当和侵权之处指出后将会立即改正还望谅解。文章分类在Python Python1---《TCP协议双向网络通讯---Python实现》 TCP协议双向网络通讯---Python实现
目录
一、TCP协议的基本特点
二、TCP协议的连接过程
三、TCP协议的数据传输过程
四、TCP协议的连接关闭过程
五、TCP协议的安全挑战与防范策略
六、Python编程实现
4.1TcpServer服务器端代码
4.2 TcpClient客户端代码
4.3 测试结果 TCPTransmission Control Protocol传输控制协议是一种面向连接的、可靠的、基于字节流的传输层通信协议。它工作在OSI模型的传输层旨在确保数据在IP网络中的可靠传输。以下是对TCP协议网络通讯的详细论述 本文主要使用Python实现TCP协议双向网络通讯即服务器和客户端都可以实现信息的收发采用多线程的方式能够实现服务器的一对多收发信息。 一、TCP协议的基本特点 面向连接TCP协议在数据传输之前必须先在通信双方之间建立连接。这种连接是一对一的即一个TCP连接只能有两个端点。连接建立后双方可以开始传输数据直到连接被关闭。使用多线程可以实现一对多等 可靠性TCP协议通过一系列机制来确保数据的可靠传输。这些机制包括序列号、确认应答、超时重传、流量控制等。TCP协议能够确保数据无差错、不丢失、不重复并且按序到达。 基于字节流TCP协议将应用程序交下来的数据看成是一连串的无结构的字节流。TCP不关心应用程序写入数据的含义和内容它只负责将这些数据以字节流的形式发送到对方。 二、TCP协议的连接过程
TCP协议的连接过程通常被称为“三次握手” 第一次握手客户端发送一个SYN同步序列号报文段到服务器并在这个报文段中设置序列号字段的值。此时客户端进入SYN_SENT状态。 第二次握手服务器收到客户端的SYN报文段后发送一个SYN/ACK同步/确认报文段给客户端确认客户端的SYN报文段并设置自己的序列号。此时服务器进入SYN_RCVD状态。 第三次握手客户端收到服务器的SYN/ACK报文段后发送一个ACK确认报文段给服务器确认服务器的SYN/ACK报文段。此时客户端和服务器都进入ESTABLISHED已建立连接状态TCP连接成功建立。 三、TCP协议的数据传输过程
TCP协议在数据传输过程中通过序列号、确认应答等机制来确保数据的可靠传输。 序列号TCP头部的序列号用于确保数据的有序传输。它表示在这个TCP段中的第一个字节的序号。在建立连接时双方都随机生成一个初始序列号ISN并以此作为后续数据传输的基准。 确认应答TCP头部中的确认应答号是接收端期望收到的下一个字节的序列号。发送端收到确认应答后可以认为所有在此之前的序列号的包已经被接收。 超时重传如果发送方在一定时间内没有收到接收方的确认应答就会认为该报文段已经丢失并重新发送该报文段。 流量控制TCP协议通过窗口大小来控制发送方的数据流量以适应接收方的处理能力。接收方在确认应答中告知发送方自己的窗口大小发送方根据这个值来控制数据的发送量。 拥塞控制TCP协议还通过拥塞控制机制来防止网络过载。当网络拥塞时TCP会减慢数据的发送速率以减轻网络的负担。 四、TCP协议的连接关闭过程
TCP协议的连接关闭过程通常被称为“四次挥手” 第一次挥手客户端发送一个FIN结束连接报文段给服务器表示客户端没有数据要发送了请求关闭连接。此时客户端进入FIN_WAIT_1状态。 第二次挥手服务器收到客户端的FIN报文段后发送一个ACK报文段给客户端确认收到客户端的FIN报文段。此时服务器进入CLOSE_WAIT状态客户端进入FIN_WAIT_2状态。 第三次挥手服务器在关闭连接前如果还有数据要发送给客户端可以继续发送数据。当服务器没有数据要发送时发送一个FIN报文段给客户端表示服务器也没有数据要发送了请求关闭连接。此时服务器进入LAST_ACK状态。 第四次挥手客户端收到服务器的FIN报文段后发送一个ACK报文段给服务器确认收到服务器的FIN报文段。此时客户端和服务器都进入CLOSED状态TCP连接成功关闭。 五、TCP协议的安全挑战与防范策略 尽管TCP协议在设计之初就考虑到了数据传输的可靠性和安全性但随着网络技术的不断发展TCP协议也面临着越来越多的安全挑战。例如TCP建立连接需要经历三次握手过程这个过程中存在被恶意利用的风险TCP协议本身并不提供加密功能因此数据在传输过程中容易被截获和篡改。
为了保障TCP协议的安全性可以采取以下防范策略
使用SSL/TLS等加密协议对TCP通信进行加密处理确保数据在传输过程中的安全性和完整性。通过限制SYN请求频率、限制连接数量等措施来防止SYN Flood攻击等恶意攻击。对于接收到的TCP数据包要验证其来源是否合法防止伪造数据 六、Python编程实现
4.1TcpServer服务器端代码
import socket # 导入socket模块用于网络通信
from threading import Thread # 导入Thread类用于多线程处理
import time # 导入time模块用于时间操作
import sys # 导入sys模块用于系统相关操作
import random # 导入random模块用于生成随机数# 创建存储对象
class Node:def __init__(self):self.Name None # 用户名self.Thr None # 套接字连接对象self.flag 0 # 标志位class TcpServer:user_name {} # 存储用户信息 dict 用户名Node对象def __init__(self, port):初始化服务器对象port: 服务器端口self.server_port port # 服务器端口self.tcp_socket socket.socket() # tcp套接字self.tcp_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # 端口重用self.tcp_socket.bind(self.server_port)self.sum 0 # 总数初始值self.flag1 0 # 标志位1self.flag2 0 # 标志位2def start(self):启动服务器self.tcp_socket.listen(100) # 设置服务器接受的链接数量print(self.get_time(), 系统等待连接)timer Thread(targetself.timer_to_order) # 创建定时发送线程timer.start()syn Thread(targetself.syn_to_order) # 创建同步发送线程syn.start()while True:try:# 监听客户端的地址和发送的消息conn, addr self.tcp_socket.accept() # 返回值为套接字和网络地址except KeyboardInterrupt: # 按下ctrlc会触发此异常self.tcp_socket.close() # 关闭套接字sys.exit(\n self.get_time() 系统服务器安全退出) # 程序直接退出不捕捉异常except Exception as e:print(e)continue# 为当前链接创建线程t Thread(targetself.do_request, args(conn, ))t.start()def do_request(self, conn):监听客户端传送的消息并将该消息发送给所有用户conn_node Node()while True:recv_data conn.recv(1024).decode(utf-8).strip() # 获取客户端发来的数据# print(recv_data)info_list recv_data.split( ) # 切割命令# print(info_list)# 如果接收到命令为exit则表示该用户退出删除对应用户信息关闭连接if recv_data exit:msg self.get_time() 系统用户 conn_node.Name 退出控制系统print(msg)self.send_to_other(conn_node.Name, msg)conn.send(exit.encode(utf-8))self.user_name.pop(conn_node.Name)conn.close()breakelse:try:A info_list[-2], info_list[-1]except IndexError:conn.send((self.get_time() 系统无法识别您的指令请重新输入).encode(gb2312))continueif info_list[-1] -n:# 新用户注册print(self.get_time() 系统 info_list[0] 连接成功)data_info self.get_time() 系统 info_list[0] 加入了控制系统self.send_to_all(data_info)conn.send(OK.encode(utf-8))conn_node.Name info_list[0]conn_node.Thr connself.user_name[info_list[0]] conn_nodeelif info_list[-1] -ta:# 群发消息# msg self.get_time() %s % conn_node.Name .join(info_list[:-1])self.sum self.sum int(info_list[0])msg self.get_time() %s贡献 % conn_node.Name .join(info_list[:-1]) 。总数%d % self.sumself.send_to_all(msg)elif info_list[-1] -tas:conn_node.flag 1self.sum self.sum int(info_list[0])msg self.get_time() %s贡献 % conn_node.Name .join(info_list[:-1]) 。总数%d % self.sumself.send_to_all(msg)def send_to_all(self, msg):对所有用户发送消息print(msg)for i in self.user_name.values():i.Thr.send(msg.encode(utf-8))def send_to_other(self, name, msg):对除了当前发送信息的用户外的其他用户发送消息# print(收到消息: msg)for n in self.user_name:if n ! name:self.user_name[n].Thr.send(msg.encode(utf-8))else:continuedef get_time(self):返回当前系统时间return [ time.strftime(%Y-%m-%d %H:%M:%S, time.localtime()) ]# 服务器定时发送指令def timer_to_order(self):while True:for i in self.user_name.values():msg {}.format(random.randint(1, 10)) -ordprint(\n给客户端发送定时指令: %s % msg)i.Thr.send(msg.encode(utf-8))time.sleep(30) # 30s定时发送一次# 服务器同步发送指令def syn_to_order(self):while True:flag_sum 0 # 标志位总和for key in self.user_name: # 获得字典的键flag_sum self.user_name[key].flag # 计算各客户端的flag位time.sleep(0.01) # 延迟10s防止迭代时字典数量改变if flag_sum len(self.user_name) and flag_sum ! 0: # 判断服务器是否都接受到flag标志end_flag 1 # 终值标志位else:end_flag 0if end_flag:print(\n)for i in self.user_name.values():msg {}.format(random.randint(1self.sum, 10self.sum)) -ordprint(给客户端发送特殊指令: %s % msg)i.Thr.send(msg.encode(utf-8))i.flag 0if __name__ __main__:HOST 127.0.0.1 # 主机回送地址,测试使用# HOST 192.168.8.111 # 局域网ip地址实际情况使用POST 9999server TcpServer((HOST, POST))server.start()
4.2 TcpClient客户端代码 可以新建多个客户端
import socket # 导入socket模块用于网络通信
from threading import Thread # 导入Thread类用于多线程处理
import time # 导入time模块用于时间操作class TcpClient:server_addr (127.0.0.1, 9999) # 服务器地址和端口order 2 # 初始指令数def __init__(self):self.tcp_cli_socket socket.socket() # 创建TCP客户端套接字def msg_recv(self):接收数据while True:data self.tcp_cli_socket.recv(1024).decode(utf-8).strip() # 接收数据并解码info_list data.split( ) # 切割命令if data exit:print(客户端退出)self.tcp_cli_socket.close()breakif info_list[-1] -ord:if int(info_list[0])/2.0 int(int(info_list[0])/2):print(\033[1;32m通过\033[0m) # 在控制台中打印通过信息绿色print(接收可行指令并更新标志数为:, int(info_list[0])) # 打印接收到的指令信息self.order int(int(info_list[0])/2.0) # 更新指令数else:print(不通过) # 打印不通过信息else:print(data) # 打印其他接收到的数据def msg_send(self):发送数据while True:data_info input(请发送指令) # 用户输入指令if data_info exit:self.tcp_cli_socket.send(data_info.encode(utf-8)) # 发送退出指令breakelse:self.tcp_cli_socket.send((data_info -ta).encode(utf-8)) # 发送带有标志的指令def order_send(self):定时发送指令while True:time.sleep(5) # 每隔5秒发送一次指令self.tcp_cli_socket.send(({}.format(self.order) -tas).encode(utf-8)) # 发送同步指令print(给服务器发送指令%d % self.order) # 打印发送的指令数def start(self):连接服务器try:self.tcp_cli_socket.connect(self.server_addr) # 连接服务器except Exception as e:print(连接失败请重试)self.tcp_cli_socket.close()print(e)returnwhile True:name input(输入客户端编号) # 输入客户端编号self.tcp_cli_socket.send((name -n).encode(utf-8)) # 发送注册指令data self.tcp_cli_socket.recv(128).decode(utf-8) # 接收服务器返回信息print(data) # 打印返回信息if data OK:print(你已成功进入服务器)breakelse:print(data)t Thread(targetself.msg_recv) # 创建信息接收线程t.start()t1 Thread(targetself.msg_send) # 创建信息发送线程t1.start()t2 Thread(targetself.order_send) # 创建定时指令发送线程t2.start()if __name__ __main__:client TcpClient()client.start()4.3 测试结果
运行服务器端 运行客户端 文章若有不当和不正确之处还望理解与指出。由于部分文字、图片等来源于互联网无法核实真实出处如涉及相关争议请联系博主删除。如有错误、疑问和侵权欢迎评论留言联系作者或者私信联系作者。