当前位置: 首页 > news >正文

九里网站开发网页ui

九里网站开发,网页ui,长兴住房和城乡建设局网站,北京网站建设排名一、多播和广播 1.1、多播 1.1.1、定义 多播#xff08;Multicast#xff09;也称为组播#xff0c;是一种一对多的通信方式#xff0c;将信息从单个源发送到 多个特定的接收者。这些接收者组成一个特定的多播组#xff0c;只有加入该组的设备才会接 收和处理多播数据。…一、多播和广播 1.1、多播 1.1.1、定义 多播Multicast也称为组播是一种一对多的通信方式将信息从单个源发送到 多个特定的接收者。这些接收者组成一个特定的多播组只有加入该组的设备才会接 收和处理多播数据。 1.1.2、特点 高效性多播避免了向每个接收者单独发送数据的重复传输从而节省了网络带 宽和发送方的资源。 例如在视频会议应用中一个演讲者的视频和音频流可以 通过多播发送给多个参与者而不是为每个参与者单独发送一份相同的流。 可管理性多播组可以动态地加入和退出便于管理和控制接收者的范围。 例 如在网络游戏中玩家可以根据自己的游戏进程加入或退出特定的多播组以 接收与特定游戏场景相关的信息。 协议支持多播通常使用特定的协议如 IP 多播使用 D 类 IP 地址范围 224.0.0.0 到 239.255.255.255。 1.1.3、应用 多媒体流传输在线视频和音频流服务可以使用多播将内容同时发送给多个用 户减少服务器的负载和网络带宽的占用。 例如网络电视、在线教育平台等可 以利用多播技术向大量用户同时推送视频课程或直播节目。 企业内部通信企业内部的视频会议、数据分发等应用可以使用多播来提高效 率。 例如公司内部的培训课程可以通过多播发送给分布在不同地点的员工而 不需要为每个员工单独建立连接。 网络游戏多人在线游戏可以使用多播来同步游戏状态和事件。 例如游戏中的 怪物移动、玩家交互等信息可以通过多播发送给同一游戏区域内的玩家减少服 务器的通信负担。 1.2、广播 1.2.1、定义 广播Broadcast是一种一对所有的通信方式将信息从单个源发送到网络中的所 有设备。广播数据包在网络中被广泛传播任何连接到该网络的设备都可以接收到广 播消息。 1.2.2、特点 广泛性广播消息可以覆盖整个网络确保所有设备都有机会接收到信息。这在 某些情况下非常有用例如网络发现、设备初始化等。 简单性广播通信相对简单不需要复杂的路由和组管理机制。发送方只需将数 据包发送到广播地址网络中的设备会自动接收并处理广播消息。 安全性广播通信的安全性较低因为任何连接到网络的设备都可以接收到广播 消息。因此当网络中存在大量的广播数据包进行传输时会导致网络的性能严重 下降。 1.2.3、应用 网络发现设备可以通过发送广播消息来发现网络中的其他设备和服务。例如 计算机在启动时可以发送广播请求以查找可用的打印机、文件服务器等资源。 DHCP 服务动态主机配置协议DHCP使用广播来分配 IP 地址和其他网络配 置参数。当计算机启动时它会发送一个 DHCP 广播请求网络中的 DHCP 服务 器会响应这个请求为计算机分配一个 IP 地址和其他必要的配置信息。 网络管理网络管理员可以使用广播来发送管理命令或查询网络状态如检查网 络中的设备是否在线、收集网络统计信息等。 二、TCP 传输控制协议TCPTransmission Control Protocol是一种面向连接的、可靠 的、基于字节流的传输层通信协议。 2.1、协议格式 源端口和目的端口各占16位用于标识发送方和接收方的应用程序进程。 序号32位标识发送数据包中的第一个字节的序列号。 确认序号32位是期望收到的下一个数据包的序列号用于确认已经收到的数据 包。 头部长度4位TCP首部的长度。 保留6位保留位暂时没有什么作用。 标志位6位包括 URG紧急指针有效、ACK确认号有效、PSH推送功 能、RST复位 TCP 连接、SYN同步报文用于建立连接、FIN没有数据 需要发送用于关闭连接。 窗口16位用来告诉TCP连接对端自己能够接收的最大数据长度。 校验和16位用来检验数据的完整性。 紧急指针16位只有 URG 标志位被设置时该字段才有意义表示紧急数据相对序 列号的偏移。  2.2、特点  面向连接 在通信之前需要通过特定的握手过程在发送方和接收方之间建立连 接。连接建立后数据可以在这个连接上可靠地传输通信结束后还需要通过特 定的挥手过程来释放连接。 可靠性高 序号与确认机制为每个发送的数据包分配一个序号接收方根据序号对收 到的数据包进行排序和确认。发送方如果在合理的往返时延内没有收到确 认就会重传数据包。 校验和计算数据包的校验和用于检测数据在传输过程中是否发生错误。 如果收到的数据包校验和有差错TCP 将丢弃这个分片。 流量控制 通过滑动窗口协议实现。接收方在确认数据包时会告知发送方自己的 接收窗口大小发送方根据这个窗口大小来控制发送数据的速率防止发送过快 导致接收方缓冲区溢出。 拥塞控制 能够根据网络的拥塞情况动态调整发送数据的速率避免网络拥塞。 例如采用慢启动、拥塞避免、快速重传和快速恢复等算法。  2.3、工作方式  2.3.1、TCP建立连接的三次握手 TCP是面向连接的协议也就是说在收发数据前必须和对方建立可靠的连接。 一个TCP连接必须要经过三次“对话”才能建立起来其中的过程非常复杂 描述下这三次对话的过程 1主机A向主机B发出连接请求“我想给你发数据可以吗”这是第一次对话 2主机B向主机A发送同意连接和要求同步 同步就是两台主机一个在发送一个在接收协调工作的数据包 “可以你什么时候发”这是第二次对话 3主机A再发出一个数据包确认主机B的要求同步“我现在就发你接着吧” 这是第三次握手。 三次“对话”的目的是使数据包的发送和接收同步 经过三次“对话”之后主机A才向主机B正式发送数据。 建立连接三次握手 第一步客户端发送 SYN同步报文给服务器端进入 SYN_SEND 状态请求建立 连接其中包含一个随机生成的初始序列号。 第二部服务器端收到 SYN 报文后回应一个 SYNseq yACKack x 1报 文进入 SYN_RECV 状态表示收到了客户端的请求并向客户端确认。 第三步客户端收到服务器端的 SYN 报文后回应一个 ACKack y 1报文进 入 ESTABLISHED 状态。服务器端接收到这个 ACK 报文后也进入 ESTABLISHED 状态此时连接建立成功可以开始传输数据。  2.3.2、TCP断开连接的四次挥手 TCP建立连接要进行3次握手而断开连接要进行4次 第一次 当主机A完成数据传输后,将控制位FIN置1提出停止TCP连接的请求 第二次 主机B收到FIN后对其作出响应确认这一方向上的TCP连接将关闭,将ACK置1 第三次 由B 端再提出反方向的关闭请求,将FIN置1 第四次 主机A对主机B的请求进行确认将ACK置1双方向的关闭结束.。 2.4、应用场景  文件传输如 FTP文件传输协议需要保证文件的完整传输使用 TCP 协议 可以确保文件传输的准确性和可靠性。 电子邮件SMTP简单邮件传输协议等电子邮件协议使用 TCP 协议来保证邮 件的可靠传输避免邮件丢失或损坏。 Web 浏览HTTP超文本传输协议基于 TCP 协议确保网页内容的正确传输 和显示。 三、UDP 用户数据报协议UDPUser Datagram Protocol是 OSI开放系统互连参考 模型中一种无连接的传输层协议提供面向事务的简单不可靠信息传送服务。 3.1、协议格式 源端口16位标识发送端的端口号用于区分不同的应用程序或进程。 目的端口16位标识接收端的端口号使数据报能够被正确地路由到接收端的应 用程序。 UDP长度16位表示 UDP 数据报的长度包括 UDP 首部和数据部分的长度。 校验和16位用于检测数据在传输过程中是否发生了错误。发送端计算数据报的 校验和并将其添加到 UDP 首部中接收端根据接收到的数据报重新计算校验和并 与数据报中的校验和进行比较以检测数据的完整性。如果校验和不匹配说明数据 报可能在传输过程中被篡改或损坏但 UDP 本身不提供错误修正机制。  3.2、特点 无连接性 通信双方在传输数据之前不需要建立连接也不需要维护连接状态。发送 方可以直接向接收方发送数据报无需事先进行握手等操作减少了连接建立和维护 的时间开销。 不可靠性 不提供数据包的确认和重传机制数据传输过程中可能会出现丢包、重复或乱序 等情况。如果数据包在传输过程中丢失或损坏UDP 协议本身不会采取任何措施 来恢复数据。 没有流量控制和拥塞控制机制不能根据网络的拥塞情况调整发送数据的速率 可能会导致网络拥塞加剧。 面向数据报以数据报为基本单位进行通信每个数据报是一个独立的、完整的消 息具有独立的头部和数据部分。UDP 不会对数据进行拆分或合并保持数据报的 边界。 轻量级 UDP 协议的头部开销较小只有 8 个字节相比 TCP 协议的 20 个字节头 部UDP 可以减少网络传输中的额外开销。 快速性 由于不需要建立连接和维护状态以及头部开销小UDP 传输速度较快 适用于对实时性要求较高的应用场景。 3.3、应用场景  实时多媒体传输如实时视频会议、网络电话VoIP、在线游戏等实时性要求 高的应用。在这些应用中偶尔丢失一两个数据包对接收结果的影响较小相比 之下更注重数据的实时传输UDP 的低延迟和快速性能够满足要求。 广播和多播通信UDP 不需要与每个接收者建立连接能够更有效地向多个目标 同时发送数据适用于广播和多播通信模式如视频直播、网络电台等应用。 简单的网络应用对于一些对数据可靠性要求不高的简单网络应用如域名系统 DNS查询。即使偶尔出现数据包丢失也可以通过重新查询来获取正确的结 果。 快速数据传输在数据传输时间很短数据量较小且对数据完整性要求不高的 情况下UDP 是一个合适的选择例如一些传感器数据的采集和传输。 四、socket编程 4.1、socket的创建 def __init__(self, family-1, type-1, proto-1, filenoNone):# For user code address family and type values are IntEnum members, but# for the underlying _socket.socket theyre just integers. The# constructor of _socket.socket converts the given argument to an# integer automatically.if fileno is None:if family -1:family AF_INETif type -1:type SOCK_STREAMif proto -1:proto 0_socket.socket.__init__(self, family, type, proto, fileno)self._io_refs 0self._closed False family指定地址族决定了套接字可以使用的地址类型。  socket.AF_INET这是最常见的地址族表示IPV4地址。使用这个地址族创建 的套接字可以在互联网上与其他IPV4主机进行通信。 socket.AF_INET6表示IPV6地址。 socket.AF_UNIX用于在同一台计算机上的不同进程之间进行通信。这种通信 方式不涉及网络而是通过文件系统中的特殊文件实现。 socket.AF_CAN用于Linux内核中实现CAN总线通信。CAN总线是一种广泛应 用于汽车、工业自动化等领域的现场总线是一种通信协议。 socket.AF_PACKET允许直接访问数据链路层的数据包这意味着可以在不经 过网络协议栈的高层处理的情况下捕获和发送原始的网络数据包。 socket.AF_RDS提供一种可靠的数据包通信机制类似于UDP但具有更高的可 靠性。 type套接字类型。 socket.SOCK_STREAM面向连接的流式套接字提供可靠的、顺序的、双向 的字节流通信。这通常用于像 TCPTransmission Control Protocol这样的协 议确保数据的完整性和顺序性。例如在进行文件传输或网页浏览时通常使 用这种类型的套接字。 socket.SOCK_DGRAM无连接的数据报套接字提供不可靠的、不保证顺序的 通信。这种类型的套接字通常用于像 UDPUser Datagram Protocol这样的 协议适用于对实时性要求较高但对数据可靠性要求不高的应用如实时视频流 或在线游戏。 socket.RAW原始套接字可以直接访问网络层的数据绕过了传输层如 TCP 和 UDP的封装。这意味着你可以自己构建 IP 数据包、ICMP 数据包等或 者捕获和分析原始的网络数据包。  proto协议编号通常为0表示自动选择合适的协议。  fileno如果指定了文件描述符则使用该文件描述符创建套接字而不是创建新的 套接字通常不指定。  4.2、常用的方法  4.2.1、 bind(address) 将套接字绑定到一个特定的地址和端口上。这个地址通常是一个元组包含 IP 地 址和端口号。例如对于 IPv4 地址 address可以是 (127.0.0.1, 8888) 表示将套接字绑定到本地回环地址 127.0.0.1 的 8888 端口上。 服务器端通常需要调用这个方法来指定监听的地址和端口以便客户端能够连接 到服务器。 4.2.2、 listen(backlog) 开始监听传入的连接请求。 backlog参数指定在拒绝连接之前可以挂起的最大 连接数量。这个参数通常用于控制服务器能够同时处理的连接请求数量。 服务器端在绑定地址后调用这个方法来开始接受客户端的连接请求。 4.2.3 accept() 接受一个传入的连接。这个方法会阻塞直到有连接请求到来然后返回一个新的 套接字对象和客户端的地址。新的套接字对象可以用于与客户端进行通信而客 户端的地址通常是一个元组包含客户端的 IP 地址和端口号。 服务器端使用这个方法来接受客户端的连接并创建一个新的套接字与客户端进 行通信。 4.2.4 connect(address) 连接到指定的地址。 address是服务器的地址和端口号组成的元组。 客户端使用这个方法来连接到服务器。 4.2.5 send(data) 发送数据。 data是要发送的字节数据这个方法会将数据发送到连接的另一 端。必须是字节串类型如果发送字符串需要先进行encode编码。 返回值是实际发送的字节数。如果发送失败可能会抛出异常。 TCP通信使用。 4.2.6 recv(bufsize) 接收数据。 bufsize指定一次最多接收的字节数。这个方法会从连接的另一端接 收数据并返回接收到的字节数据。接收到的是字节串需要使用decode进行解 码。 如果没有数据可接收这个方法会阻塞直到有数据到来或者连接关闭。如果连 接关闭返回一个空字节串。 TCP通信使用。 4.2.7 close() 关闭套接字。这个方法会释放套接字占用的资源并关闭连接。 在通信结束后无论是服务器端还是客户端都应该调用这个方法来关闭套接字。 4.2.8 sendto(data, address) data是要发送的数据。必须是字节码发送时需要先使用encode进行编码。 address一个二元组包含目标地址和端口号。例如(127.0.0.1,8888)表示将数据发送到本地回环地址的 8888 端口。 主要用于 UDP 。 4.2.9 recvfrom(bufsize, flags) bufsize表示要接受的最大字节数。flags是一个可选参数和系统有关使用默 认值即可。 它会返回一个二元组 (data, address)其中 要使用decode进行解码 data是接收到的字节串数据需 address是发送方的地址信息通常是一个二元组 (IP 地址, 端口号)。 主要用于 UDP 。 与 TCP 的 recv()对比在 TCP 中数据的接收是通过已经建立的连接进行的 通常使用 recv()方法该方法只返回接收到的数据而不需要同时获取发送方 的地址信息因为在 TCP 连接中已经知道了通信的对端地址。 4.2.10 其他常用函数 1. getsockname()返回套接字自己的地址。 2. getpeername()返回连接对象的地址。 3. gethostname()返回一个字符串包含当前正在运行 Python 解释器的机器的 主机名。 4. gethostbyname(hostname) 解析主机名返回第一个匹配的IP地址。 5. gethostbyname_ex(hostname) 解析主机名返回一个包含主机别名和地址 列表的元组。 6. gethostbyaddr(ip_address) 返回一个三元组hostname, aliaslist, ipaddrlisthostname是主机名aliaslist是其他可用主机名列表可能为 空ipaddrlist是ipv4/v6地址列表。 7. setblocking(bool)设置套接字为阻塞或非阻塞模式。 8. settimeout(value)为阻塞套接字的操作设置超时时间是一个非负数。如 果是非零值那么在操作完成前超过了指定时间那么就会抛出异常如果是 0将处于非阻塞模式如果为None将处于阻塞模式。 4.3、 C/S架构 client客户端 Server服务器 4.3.1、TCP服务器 在Python语言中创建Socket服务端程序需要使用socket模块中的 socket类。创建Socket服务器程序的步骤如下 1 创建Socket对象。 2 绑定端口号。 3 监听端口号。 4 等待客户端Socket的连接。 5 读取客户端发送过来的数据。 6 向客户端发送数据。 7 关闭客户端Socket连接。 8 关闭服务端Socket连接。 TCP服务器端接收数据 from socket import * # 导入 socket 模块中的所有内容 # 创建一个 TCP 套接字 server_socket socket(AF_INET, SOCK_STREAM) # 绑定套接字到本地 IP 地址和端口号8899 server_socket.bind((127.0.0.1, 8899)) # 监听连接最多允许 5 个待处理的连接 server_socket.listen(5) # 接受客户端的连接请求返回客户端套接字和其信息 client_socket, client_info server_socket.accept() # 接收来自客户端的数据最多接收 1024 字节 recv_data client_socket.recv(1024) # 打印接收到的信息解码为 gbk 编码及客户端信息 print(f收到信息:{recv_data.decode(gbk)},来自:{client_info}) # 关闭与客户端的连接 client_socket.close() # 关闭服务器套接字 server_socket.close() TCP客户端发送数据到服务端 from socket import * # 导入 socket 模块中的所有内容 # 创建一个 TCP 套接字 client_socket socket(AF_INET, SOCK_STREAM) # 连接到指定的服务器 IP 地址和端口号8899 client_socket.connect((127.0.0.1, 8899)) # 发送字符串 haha并将其编码为 gbk 格式 client_socket.send(haha.encode(gbk)) # 关闭与服务器的连接 client_socket.close() TCP双向通信Socket之服务器端  #导入socket模块 from socket import * #创建Socket对象 tcp_server_socketsocket(AF_INET, SOCK_STREAM) #绑定端口 tcp_server_socket.bind((, 8888)) #监听客户端的连接 tcp_server_socket.listen() print(服务端已经启动等待客户端连接) #接收客户端连接 tcp_client_socket,hosttcp_server_socket.accept() print(一个客户端建立连接成功) while True:#读取客户端的消息re_datatcp_client_socket.recv(1024).decode(gbk)#将消息输出到控制台print(客户端说,re_data)if re_dataend:break#获取控制台信息msginput()tcp_client_socket.send(msg.encode(gbk)) tcp_client_socket.close() tcp_server_socket.close() TCP双向通信Socket之客户端  # 导入socket模块 from socket import *# 创建客户端Socket对象 tcp_client_socket socket(AF_INET,SOCK_STREAM) # 连接服务器端 tcp_client_socket.connect((127.0.0.1,8888)) while True:msg input()# 向服务器发送数据tcp_client_socket.send(msg.encode(gbk))if msg end:break# 接收服务器端数据re_data tcp_client_socket.recv(1024)print(服务器端说,re_data.decode(gbk)) tcp_client_socket.close()多线程实现TCP双向传送(自由聊天)  TCP服务端结合多线程实现自由收发信息 #导入socket模块 from socket import * from threading import Thread def recv_data():while True:# 读取客户端的消息re_data tcp_client_socket.recv(1024).decode(gbk)# 将消息输出到控制台print(f客户端说:{re_data})if end in re_data:break def send_data():while True:# 获取控制台信息msg input()tcp_client_socket.send(msg.encode(gbk))if __name__ __main__:# 创建Socket对象tcp_server_socket socket(AF_INET,SOCK_STREAM)# 绑定端口tcp_server_socket.bind((, 8888))# 监听客户端的连接tcp_server_socket.listen()print(服务端已经启动等待客户端连接)# 接收客户端连接tcp_client_socket, host tcp_server_socket.accept()print(一个客户端建立连接成功)t1 Thread(targetrecv_data)t2 Thread(targetsend_data)t1.start()t2.start()t1.join()t2.join()tcp_client_socket.close()tcp_server_socket.close() TCP客户端结合多线程实现自由收发信息 #导入socket模块 from socket import * from threading import Thread def recv_data():while True:# 接收服务器端数据re_data tcp_client_socket.recv(1024)print(f\n服务器端说:{re_data.decode(gbk)}) def send_data():while True:msg input()# 向服务器发送数据tcp_client_socket.send(msg.encode(gbk))if endin msg:break if __name__ __main__:# 创建客户端Socket对象tcp_client_socket socket(AF_INET,SOCK_STREAM)# 连接服务器端tcp_client_socket.connect((127.0.0.1,8888))t1 Thread(targetrecv_data)t2 Thread(targetsend_data)t1.start()t2.start()t1.join()t2.join()tcp_client_socket.close() 4.3.2、UDP服务器 UDP协议时不需要建立连接只需要知道对方的IP地址和端口 号就可以直接发数据包。但是能不能到达就不知道了。虽然用 UDP传输数据不可靠但它的优点是和TCP比速度快对于不要 求可靠到达的数据就可以使用UDP协议。 创建Socket时 SOCK_DGRAM 指定了这个Socket的类型是UDP。绑定 端口和TCP一样但是不需要调用 listen() 方法而是直接接收来自任 何客户端的数据。 recvfrom() 方法返回数据和客户端的地址与端口这 样服务器收到数据后直接调用 sendto() 就可以把数据用UDP发给 客户端。 UDP接收数据 from socket import * s socket(AF_INET, SOCK_DGRAM) #创建套接字 #绑定接收信息端口 s.bind((127.0.0.1, 8888)) #绑定一个端口ip地址和端⼝号 print(等待接收数据) redata s.recvfrom(1024) #1024表示本次接收的最⼤字节数 print(redata) print(f收到远程信息:{redata[0].decode(gbk)}, from {redata[1]}) s.close() UDP发送数据  from socket import * s socket(AF_INET, SOCK_DGRAM) #创建套接字 addr (127.0.0.1, 8888) #准备接收方地址 data input(请输入) #发送数据时python3需要将字符串转成byte s.sendto(data.encode(gbk),addr) #默认的网络助手使用的编码是gbk s.close() 持续通信  UDP接收数据  from socket import * s socket(AF_INET,SOCK_DGRAM) #创建UDP类型的套接字 s.bind((127.0.0.1,8888)) #绑定端口,ip可以不写 print(等待接收数据) while True:recv_data s.recvfrom(1024)#1024表示本次接收的最大字节数recv_content recv_data[0].decode(gbk)print(f收到远程信息:{recv_content},from{recv_data[1]})if recv_content 88:print(结束聊天)break s.close() UDP发送数据 from socket import * s socket(AF_INET,SOCK_DGRAM) #创建UDP类型的套接字 addr (127.0.0.1,8888) while True:data input(请输入)s.sendto(data.encode(gbk), addr)if data 88:print(结束聊天)break s.close() 结合多线程实现UDP双向自由通信  UDP 不同于 TCP不存在请求连接和受理过程因此在某种意 义上无法明确区分服务器端和客户端只是因为其提供服务而 称为服务器端。  UDP实现多线程服务端  #codingutf-8 from socket import * from threading import Thread udp_socketsocket(AF_INET,SOCK_DGRAM) #绑定接收信息端口 udp_socket.bind((127.0.0.1,8989)) #不停接收 def recv_data():while True:redata udp_socket.recvfrom(1024)print(f收到信息:{redata[0].decode(gbk)}, from{redata[1]}) #不停发送 def send_data():while True:datainput(输入信息)addr(127.0.0.1,8080)udp_socket.sendto(data.encode(gbk),addr) if __name____main__:# 创建两个线程t1Thread(targetsend_data)t2Thread(targetrecv_data)t2.start()t1.start()t1.join()t2.join() UDP实现多线程客户端  from socket import * from threading import Thread udp_socketsocket(AF_INET,SOCK_DGRAM) #绑定接收信息端口 udp_socket.bind((127.0.0.1,8080)) #不停接收 def recv_data():while True:redata udp_socket.recvfrom(1024)print(f收到信息:{redata[0].decode(gbk)}, from{redata[1]}) #不停发送 def send_data():while True:datainput(输入信息)addr(127.0.0.1,8989)udp_socket.sendto(data.encode(gbk),addr) if __name____main__:# 创建两个线程t1Thread(targetsend_data)t2Thread(targetrecv_data)t2.start()t1.start()t1.join()t2.join() 五、并发编程 5.1、多进程 服务端 import socket from multiprocessing import Process def func(connection, client_address):print(f{client_address}已连接)while True:try:# 从连接套接字接收最多 1024 字节的数据data connection.recv(1024)# 打印接收到的来自客户端的数据print(f接收来自{client_address}的数据{data.decode()})response 你发过来的数据是 data.decode()connection.send(response.encode())except ConnectionAbortedError:print(f{client_address}连接已断开)# 关闭与客户端的连接套接字connection.close()break if __name__ __main__:# 创建一个 IPv4 的 TCP 套接字server_socket socket.socket(socket.AF_INET,socket.SOCK_STREAM)# 定义服务器的地址和端口server_address (127.0.0.1, 43999)# 将套接字绑定到指定的地址和端口server_socket.bind(server_address)# 开始监听连接请求参数 5 表示允许排队等待的连接数量server_socket.listen(5)print(服务器已启动...)while True:# 接受一个客户端的连接请求返回一个新的连接套接字和客户端地址connection, client_address server_socket.accept()Process(targetfunc, args(connection,client_address)).start() 客户端 import socket import time # 创建一个 IPv4 的 TCP 套接字 client_socket socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 定义服务器的地址和端口 server_address (127.0.0.1, 43999) # 客户端连接到服务器的地址和端口 client_socket.connect(server_address) i 0 while True:if i 3:breakclient_socket.send(str(i).encode())# 客户端接收来自服务器的最多 1024 字节的数据data client_socket.recv(1024)# 打印接收到的来自服务器的响应消息print(f来自服务器的响应为{data.decode()})i 1time.sleep(1) # 关闭客户端套接字 client_socket.close() 5.2、多线程 服务端 import socket from threading import Thread def func(connection, client_address):print(f{client_address}已连接)while True:try:# 从连接套接字接收最多 1024 字节的数据data connection.recv(1024)# 打印接收到的来自客户端的数据print(f接收来自{client_address}的数据{data.decode()})response 你发过来的数据是 data.decode()connection.send(response.encode())except ConnectionAbortedError:print(f{client_address}连接已断开)# 关闭与客户端的连接套接字connection.close()break if __name__ __main__:# 创建一个 IPv4 的 TCP 套接字server_socket socket.socket(socket.AF_INET,socket.SOCK_STREAM)# 定义服务器的地址和端口server_address (127.0.0.1, 43999)# 将套接字绑定到指定的地址和端口server_socket.bind(server_address)# 开始监听连接请求参数 5 表示允许排队等待的连接数量server_socket.listen(5)print(服务器已启动...)while True:# 接受一个客户端的连接请求返回一个新的连接套接字和客户端地址connection, client_address server_socket.accept()Thread(targetfunc, args(connection,client_address)).start() 客户端 import socket import time # 创建一个 IPv4 的 TCP 套接字 client_socket socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 定义服务器的地址和端口 server_address (127.0.0.1, 43999) # 客户端连接到服务器的地址和端口 client_socket.connect(server_address) i 0 while True:if i 3:breakclient_socket.send(str(i).encode())# 客户端接收来自服务器的最多 1024 字节的数据data client_socket.recv(1024)# 打印接收到的来自服务器的响应消息print(f来自服务器的响应为{data.decode()})i 1time.sleep(1) # 关闭客户端套接字 client_socket.close() 5.3、协程 在asyncio库中有关于网络编程的一些函数它们处于事件循环下面 1. loop.sock_recv(sock, nbytes)异步版本的socket.recv()从sock接收至多 nbytes大小的消息。 2. loop.sock_sendall(sock, data)异步版本的socket.sendall()向sock发送 data该方法会持续发送直到数据发送完毕或抛出异常。 3. loop.sock_connect(sock, address)异步版本的socket.connect()用来连接服 务器。 4. loop.sock_accept(sock)异步版本的socket.accept()用来让服务器接收连接。 这些方法要求socket必须是非阻塞型的所以需要设置socket.setblocking 服务端 import asyncio import socket async def handle_client(client_socket, client_address, loop):print(f{client_address}已成功连接服务器...)try:while True:data await loop.sock_recv(client_socket, 1024)if not data:print(f{client_address}已断开连接...)breakprint(f{client_address}发来消息{data.decode()})message 你发过来的消息是 data.decode()await loop.sock_sendall(client_socket,message.encode())except Exception as e:print(f{client_address}连接出现问题{e})finally:client_socket.close() async def main():server_socket socket.socket(socket.AF_INET,socket.SOCK_STREAM)server_socket.bind((127.0.0.1, 43999))server_socket.listen(5)server_socket.setblocking(False)print(服务器已启动...)loop asyncio.get_running_loop()while True:client_socket, client_address await loop.sock_accept(server_socket)asyncio.create_task(handle_client(client_socket,client_address, loop)) asyncio.run(main()) 客户端 import socket import asyncio async def main():client_socket socket.socket(socket.AF_INET,socket.SOCK_STREAM)server_address (127.0.0.1, 43999)client_socket.connect(server_address)client_socket.setblocking(False)print(已成功连接服务器...)loop asyncio.get_running_loop()while True:try:await loop.sock_sendall(client_socket, 我是客户端.encode())data await loop.sock_recv(client_socket, 1024)print(从服务器返回的数据是, data.decode())await asyncio.sleep(1)except Exception as e:print(客户端异常连接已退出...)client_socket.close()break asyncio.run(main()) 除了底层API之外协程里还封装了一些高级API  1. asyncio.start_server用于服务器端用来创建并启动服务器并对连接到的客 户端进行绑定。 asyncio.start_server(client_connected_cb, hostNone, portNone, *, loopNone, ) client_connected_cb: 必需的回调函数当有新的客户端连接到服务器时会 自动调用这个回调函数来处理与该客户端的通信。这个函数应该是一个协程函 数它接受两个参数 reader 和 writer。 reader 是一个实现了异步读取数 据的方法的对象 writer 是一个实现了异步写入数据的方法的对象。 host: 可选参数用于指定服务器的IP地址或域名。如果为None则默认监听所 有可用接口IPv4或IPv6。 port: 可选参数用于指定服务器的端口号。如果为None则默认随机选择一个 可用端口。 loop: 可选参数用于指定一个事件循环。如果未提供则使用默认的事件循 环默认为None即可。 该函数返回的是一个 asyncio.Server对象。这个对象代表了正在运行的服务器可 以用于停止服务器也可以通过其属性获取一些关于服务器的信息比如 server.sockets可以获取服务器正在监听的套接字列表等。 2. asyncio.open_connection用于客户端用于建立到指定主机和端口的异步 连接并返回一对 (reader, writer) 对象其中reader 用于读取来自连接的数据 writer 用于向连接写入数据。 asyncio.open_connection(hostNone, portNone, *, loopNone, )  host指定要连接的服务器地址。如果为 None会根据其他参数如 sock 的情况进行处理。如果没有提供套接字并且 host 也为 None则会引发异常。 port指定要连接的服务器端口号。如果为 None并且没有提供套接字同样 会引发异常。 loop: 可选参数用于指定一个事件循环。如果未提供则使用默认的事件循 环默认为None即可。  3. reader.read(n-1)至多读取 n 个byte。 如果没有设置 n , 则自动置为 -1 -1时表示读至 EOF 并返回所有读取的byte。 4. writer.write(data)此方法会尝试立即将 data 写入到下层的套接字。 如果写 入失败数据会被排入内部写缓冲队列直到可以被发送。此方法应当与 drain() 方法一起使用。 5. writer.drain()阻塞当前协程直到底层的缓冲区有足够的空间可以继续写入 数据或者数据已经全部发送出去从而确保数据能够正确、完整地发送到对 端。 6. writer.wait_closed()等待直到流被关闭。应当在close()之后被调用以便等待 直到下层的连接被关闭。 服务端 import asyncio # 定义一个异步函数用于处理每个客户端连接 async def handle_client(reader, writer):addr writer.get_extra_info(peername) # 获取客户端的地址信息print(f{addr} 已连接) # 打印客户端连接的信息try:# 使用一个无限循环来持续读取客户端数据while True:data await reader.read(1024) # 非阻塞地读取最多1024字节的数据# 检查是否读取到空字节串如果是则客户端已断开连接if not data:print(f{addr} 连接已断开)break# 如果有数据则打印接收到的数据print(f接收来自{addr}的数据{data.decode()})# 构造响应消息并发送回客户端response 你发过来的数据是 data.decode()writer.write(response.encode())await writer.drain() # 确保所有写入的数据都被发送出去except Exception as e:# 打印其他可能的异常print(f处理{addr}时发生异常{e})finally:# 确保关闭连接writer.close()await writer.wait_closed() # 等待连接真正关闭 # 主函数用于启动服务器 async def main():# 创建服务器指定处理客户端连接的回调函数以及服务器监听的地址和端口server await asyncio.start_server(handle_client,127.0.0.1, 43999)# 获取服务器监听的地址信息addr server.sockets[0].getsockname()print(f服务器在 {addr} 启动...) # 打印服务器启动的信息async with server:# 使用异步上下文管理器来确保服务器正确关闭await server.serve_forever() # 使服务器一直运行直到显式停止 # 当作为主模块运行时启动服务器 if __name__ __main__:asyncio.run(main()) # 使用asyncio.run启动主协程 客户端 import asyncio async def client():reader, writer await asyncio.open_connection(127.0.0.1, 43999)addr writer.get_extra_info(sockname)for i in range(3):writer.write(str(addr).encode())await writer.drain()data await reader.read(1024)print(f来自服务器的响应为{data.decode()})await asyncio.sleep(1)writer.close()await writer.wait_closed() async def main():await asyncio.gather(client(),client(),client(),# 可以添加更多 client() 调用来模拟多个客户端连接) if __name__ __main__:asyncio.run(main()) 5.4、IO多路复用 IO 多路复用是一种可以同时监控多个 IO 源比如多个网络连接、多个文件描述符 等的技术当其中任何一个 IO 源准备好进行读写操作时程序就可以进行相应的 处理而不需要阻塞地等待每个 IO 源逐个完成操作。 常见的IO多路复用机制有三种 1. selectWindows、Linux都有它是最早出现的 IO 多路复用机制。它通过 一个文件描述符集合来监控多个 IO 源当有 IO 源准备好时 select函数返 回然后程序可以遍历集合找出准备好的 IO 源进行处理。但是 select有一些限 制比如监控的文件描述符数量有限制并且每次调用都需要重新设置监控的文 件描述符集合。 2.poll只存在于Linux系统中和select类似但没有文件描述符数量的限 制。不过当文件描述符数量很多时它的性能也不是很高。 3. epoll只存在于Linux 系统中 epoll是一种高效的 IO 多路复用机制。它通 过事件驱动的方式当 IO 源准备好时内核会将事件通知程序避免了像 select和 poll那样需要不断地遍历文件描述符集合。 服务端 import socket import select server_socket socket.socket(socket.AF_INET, socket.SOCK_STREAM) address (127.0.0.1, 43999) server_socket.bind(address) server_socket.listen(5) print(服务器已启动...) inputs [server_socket] while True:rlist, wlist, xlist select.select(inputs, [], [])for sock in rlist:if sock is server_socket:connection, client_address sock.accept()inputs.append(connection)else:try:data sock.recv(1024)if not data:print(f{sock.getpeername()}已断开连接)inputs.remove(sock)sock.close()else:print(f接收来自{sock.getpeername()}的数据{data.decode()})response 你发过来的数据是 data.decode()sock.send(response.encode())except Exception as e:print(e)inputs.remove(sock)sock.close() 客户端 import socket import time import threading def func(id):# 创建一个 IPv4 的 TCP 套接字client_socket socket.socket(socket.AF_INET,socket.SOCK_STREAM)# 定义服务器的地址和端口server_address (127.0.0.1, 43999)# 客户端连接到服务器的地址和端口client_socket.connect(server_address)message str(client_socket.getpeername()) str(id)while True:client_socket.send(message.encode())# 客户端接收来自服务器的最多 1024 字节的数据data client_socket.recv(1024)# 打印接收到的来自服务器的响应消息print(f来自服务器的响应为{data.decode()})time.sleep(1) thread_list [] while True:for i in range(200):t threading.Thread(targetfunc, args(i, ))t.start()thread_list.append(t)for th in thread_list:th.join() 六、思维导图
http://www.w-s-a.com/news/48831/

相关文章:

  • 南昌知名的网站建设公司南京网站开发选南京乐识赞
  • 外贸网站建设 深圳seo怎么提升关键词的排名
  • 网站推广效果的评价google关键词
  • 模板网站建站哪家好做微信充值网站
  • 抽奖的网站怎么做的广州小程序定制开发
  • 网站的文件夹建设企业网站公积金
  • 做网站的的价位网站建设 考试题目
  • 深圳比邻网站建设北京优化服务
  • 菏泽网站建设哪家好电子商务网络安全
  • 仿一个网站广州网站建设正规公司
  • 网站建设 目的seo网站关键词排名快速
  • 什么叫做响应式网站自媒体全平台发布
  • 企业网站 案例哪里需要人做钓鱼网站
  • 厚街东莞网站建设网站开发者调试模式
  • 网站推广营销联系方式wordpress adminlte
  • 哪些网站可以做文字链广告卖水果网站建设的策划书
  • 雕刻业务网站怎么做企业qq官网
  • 新华书店的做的数字阅读网站wordpress编辑器格式
  • jq做6个网站做什么好广西临桂建设局网站
  • 网站新闻图片尺寸南京网站设计公司
  • 重庆seo建站网站服务器 安全
  • 咸宁做网站的公司桂林网站建设兼职
  • 教做网站网站开发行业分析
  • 忻州网站建设培训友情链接交换形式有哪些
  • 佛山做外贸网站渠道外贸常用网站
  • 文章收录网站网站及新媒体建设办法
  • 招聘网站排行榜2021找建网站公司
  • 网站建设制作宝塔面板活动宣传推广的形式有哪些
  • 掉关键词网站敏捷软件开发流程
  • 微信小程序格泰网站建设新闻采编与制作专业简历