扬州天猫网站建设,柬埔寨做网站,wordpress常用插件汇总,wordpress轮播图调用一 socket网络及差别介绍
TCP#xff08;传输控制协议#xff09;和UDP#xff08;用户数据报协议#xff09;是两种常见的互联网传输协议#xff0c;它们之间有很多区别#xff0c;包括以下几个主要方面#xff1a;
1.1 TCP
TCP是传输控制协议#xff0c;是面向连接…一 socket网络及差别介绍
TCP传输控制协议和UDP用户数据报协议是两种常见的互联网传输协议它们之间有很多区别包括以下几个主要方面
1.1 TCP
TCP是传输控制协议是面向连接的通讯协议如打电话通过三次握手建立连接通讯完成时四次挥手一般应用在对安全性、完整性有严格要求的场景,如FTP、SMTP、HTTP等
优点TCP 具有高可靠性确保传输数据的正确性不出现丢失或乱序缺点TCP相对于UDP速度慢一点效率低而且要求系统资源较多每个连接都会占用系统的CPU、内存等硬件资源
1.2 UDP
UDP是用户数据报协议是面向无连接的通讯协议如发短信
优点UDP速度快、操作简单、要求系统资源较少缺点不可靠可能会出现丢包、乱序、数据不完整
1.3 TCP 与 UDP 的区别
连接 TCP 是面向连接的传输层协议传输数据前先要建立连接。UDP 是不需要连接即刻传输数据。服务对象 TCP 是一对一的两点服务即一条连接只有两个端点。UDP 支持一对一、一对多、多对多的交互通信可靠性 TCP 是可靠交付数据的数据可以无差错、不丢失、不重复、按序到达。UDP 是尽最大努力交付不保证可靠交付数据。拥塞控制、流量控制 TCP 有拥塞控制和流量控制机制保证数据传输的安全性。UDP 则没有即使网络非常拥堵了也不会影响 UDP 的发送速率。首部开销 TCP 首部长度较长会有一定的开销首部在没有使用「选项」字段时是 20 个字节如果使用了「选项」字段则会变长的。UDP 首部只有 8 个字节并且是固定不变的开销较小对系统资源要求较少。实时性 UDP 具有较好的实时性工作效率比 TCP 协议高。
1.4 应用场景
由于 TCP 是面向连接能保证数据 的可靠性交付因此经常用于(20/21端口)FTP 文件传输、HTTP / HTTPS(80端口) 、SMTP(简单邮件传送协议)、TELNET(远程终端协议)由于 UDP 面向无连接它可以随时发送数据再加上UDP本身的处理既简单又高效因此经常用于包总量较少的通信如 DNS 、SNMP、TFTP(简单文件传输协议) 等、视频、音频等多媒体通信、广播通信
1.5 Socket数据传输方式
常用的有两种
SOCK_STREAM表示面向连接的数据传输方式。数据可以准确无误地到达另一台计算机如果损坏或丢失可以重新发送但效率相对较慢。常见的 http 协议就使用 SOCK_STREAM 传输数据因为要确保数据的正确性否则网页不能正常解析。针对于面向连接的TCP服务应用SOCK_DGRAM表示无连接的数据传输方式。计算机只管传输数据不作数据校验如果数据在传输中损坏或者没有到达另一台计算机是没有办法补救的。也就是说数据错了就错了无法重传。因为 SOCK_DGRAM 所做的校验工作少所以效率比 SOCK_STREAM 高。对应于无连接的 UDP服务应用。
1.6 服务器端
from socket import *
server socket(AF_INET, SOCK_DGRAM)
server_host_port (127.0.0.1, 6000) # 服务器的IP地址和端口# 接收数据前绑定端口
server.bind(server_host_port)while True:# 接收数据data server.recvfrom(1024)# print(data:, data) # (b\xe4\xbd\xa0\xe5\xa5\xbd, (127.0.0.1, 61328))print(访问者:, data[0].decode(utf-8)) # 你好# print(f客户端的IP{data[1][0]} \n客户端的端口{data[1][1]})重新发送数据send_data input(客服说)server.sendto(send_data.encode(utf-8), data[1])# server.close()1.7 客户端
from socket import *
client socket(AF_INET, SOCK_DGRAM)
server_host_port (127.0.0.1, 6000) # 指定数据接收方while True:data input(访问者)data data.encode(utf-8)client.sendto(data, server_host_port) # 发送数据if data.decode(utf-8) bye:break接收返回数据数据recv_data client.recvfrom(1024)print(f客服说{recv_data[0].decode(utf-8)})print(程序关闭)
client.close()
二 UDP协议
udp的交互使用sendto 和 recvfrom
SOCK_DGRAM表示无连接的数据传输方式。计算机只管传输数据不作数据校验如果数据在传输中损坏或者没有到达另一台计算机是没有办法补救的。也就是说数据错了就错了无法重传。因为 SOCK_DGRAM 所做的校验工作少所以效率比 SOCK_STREAM 高。对应于无连接的 UDP服务应用。
2.1 服务器代码
from socket import *
import struct
server_socket socket(AF_INET, SOCK_DGRAM)host_port (localhost, 8888) # 端口号# 开始监听
server_socket.bind(host_port)# 接收数据
data server_socket.recvfrom(1024)
print(data, type(data))# 解析操作码
recv_data data[0]
new_data struct.unpack(!H, recv_data[:2])
print(客户端请求的操作码, new_data)# 解析文件名
file_name recv_data[2:-7].decode(utf-8)
print(客户端请求下载的文件名, file_name)
server_socket.close()
2.2 客户端代码
from socket import *
import struct
client_socket socket(AF_INET, SOCK_DGRAM)host_port (localhost, 8888) # 端口号file_name input(请输入需要上传的文件名).encode(utf-8)
print(file_name:, file_name, len(file_name))
data struct.pack(!H%dsb5sb % len(file_name), 1, file_name, 0, octet.encode(utf-8), 0)# 发送数据
client_socket.sendto(data, host_port)
client_socket.close()
三 TCP协议
tcp的交互使用send 和 recv
SOCK_STREAM表示面向连接的数据传输方式。数据可以准确无误地到达另一台计算机如果损坏或丢失可以重新发送但效率相对较慢。常见的 http 协议就使用 SOCK_STREAM 传输数据因为要确保数据的正确性否则网页不能正常解析。针对于面向连接的TCP服务应用
3.1 TCP服务器代码
from socket import *
import random# 创建SOCKET对象
server_socket socket(AF_INET, SOCK_STREAM)# 绑定IP和端口
host_port (, 6666) # 不写本机所有
server_socket.bind(host_port)# 设置listen
server_socket.listen(5)while True:# 等待客户端连接client_socket, addr server_socket.accept()print(客户端已连接3次握手完成 )# print(client_socket:, client_socket)# 接收数据data client_socket.recv(1024).decode(utf8)print(data:, data)oper_code data.split(:)[0] # 操作码recv_data data.split(:)[1] # 需要上传和下载的文件if oper_code 1: # 下载操作file_read open(recv_data, r, encodingutf8)data file_read.read()# 将数据发给客户端client_socket.send(data.encode(utf-8))file_read.close()elif oper_code 2: # 上传操作file_write open(str(random.randint(1000, 9999)) .txt, w, encodingutf-8)file_write.write(recv_data)file_write.close()print(服务器接收完成)elif oper_code 0: # 已退出print(recv_data)3.2 客户端代码
from socket import *while True:client_socket socket(AF_INET, SOCK_STREAM)# 指定要连接的IPhost_port (127.0.0.1, 6666)# 开始连接服务器client_socket.connect(host_port)choice eval(input(请选择操作 0.退出 1.下载 2.上传 \n))if choice 1:file_name input(请输入要下载的文件名)# 告诉服务器要下载的文件名join_data (str(choice) : file_name).encode(utf-8)# 发送数据client_socket.send(join_data)# 接收服务器返回的数据recv_data client_socket.recv(1024).decode(utf-8)# 写入本地磁盘download open(file_name, w, encodingutf-8)download.write(recv_data)download.close()print(下载完成)elif choice 2: # 上传path_name input(请输入要上传的文件名)# 本地读取upload open(path_name, r, encodingutf-8)upload_data upload.read()# 拼接数据结构data (str(choice) : upload_data).encode(utf-8)# 向服务器发送数据client_socket.send(data)upload.close()print(数据上传成功)elif choice 0:# 告诉服务器已退出client_socket.send((str(choice) : 客户端已退出).encode(utf-8))breakprint(客户端关闭)
TCP连接时三次握手 第一次客户端向服务器端发送连接报文SYN1同时选择一个初始序列号 seqx一起发送 第二次服务器收到报文后向客户端发报文确认报文为(ACK1SYN1)确认号为ackx1同时服务器初始化一个序列号seqy一起发送 第三次客户端向服务器端发送报文ACK1同时发送ackx1,seqy1进行确认
TCP断开时四次挥手开时四次挥手 第一次客户端发送释放报文并停止发送数据FIN1带上序列号 sequ客户端进入终止等待状态FIN-WAIT-1 第二次服务器收到报文后释放报文发出确认报文ACK1acku1并且带上序列号 seqv服务器进入关闭等待状态(CLOSE-WAIT) 第三次服务器在数据传输完毕后发送连接释放报文FIN1acku1同时发送序列号seqw服务器进入最后确认状态LAST-ACK 第四次客户端收到释放报文后向服务器发送报文ACK1ackw1发送序列号 sequ1客户端进入时间等待状态TIME-WAIT。服务器接收到报文后直接关闭客户端需要等2**MSL最长报文段寿命后结束
四 使用TCP传输较大的文件
4.1 服务端代码
from socket import *
import struct
server_socket socket(AF_INET, SOCK_STREAM) # TCPhost_port (, 6666)
server_socket.bind(host_port)server_socket.listen(1024)
# 开始监听
conn_socket, addr server_socket.accept()
print(查看服务器接收到的请求地址, addr)# 接收数据
data_header conn_socket.recv(4)
# 解包
size struct.unpack(!i, data_header)[0]
print(size:, size)# 将收到的数据上传到磁盘
file open(a.pptx, wb)
recv_size 0
while recv_size size:data_pack conn_socket.recv(1024)recv_size len(data_pack)file.write(data_pack)file.close()
print(服务器接收完成)
conn_socket.close()
server_socket.close()4.2 客户端代码
from socket import *
import os.path
import structclient_socket socket(AF_INET, SOCK_STREAM)
client_socket.connect((192.168.146.1, 6666))# 发送内容
file_path ./111.pptx# 获取文件大小
size os.path.getsize(file_path)
print(size:, size)# 对struct数据进行打包
data struct.pack(!i, size)
# 发送数据
client_socket.send(data)file open(file_path, rb)
# 循环读取 1024
while True:data_pack file.read(1024)if not data_pack:breakclient_socket.send(data_pack) # 直接发client_socket.close()