网络编程中的TCP和UDP

 

什么是TCP协议

TCP( Transmission control protocol )即传输控制协议,是一种面向连接、可靠的数据传输协议,它是为了在不可靠的互联网上提供可靠的端到端字节流而专门设计的一个传输协议。

  • 面向连接 :数据传输之前客户端和服务器端必须建立连接

  • 可靠的 :数据传输是有序的 要对数据进行校验

 

TCP三次握手

为了保证客户端和服务器端的可靠连接,TCP建立连接时必须要进行三次会话,也叫TCP三次握手,进行三次握手的目的是为了确认双方的接收能力和发送能力是否正常。

  1. 第一次握手(呼叫请求)
    • 你(客户端):想要和某人通话,于是你拿起电话,拨打对方的号码。这个动作相当于TCP中的SYN(同步序列编号)包发送。你告诉对方(服务器):“嘿,我在这里,我想和你建立通话。”
  2. 第二次握手(接听确认)
    • 对方(服务器):听到电话铃声后,接起电话,并对你的呼叫做出响应。这相当于TCP中的SYN-ACK(同步确认)包发送。对方(服务器)说:“我听到了,我也在这里,我们可以开始通话了。”同时,对方(服务器)也确认了你的存在,并准备好接下来的通信。
  3. 第三次握手(确认接听)
    • 你(客户端):在听到对方的接听确认后,你回应一个确认信号,告诉对方你已经准备好开始通话了。这相当于TCP中的ACK(确认)包发送。你说:“好的,我已经准备好了,我们可以开始通话了。”

 

  • 第一次握手 TCP客户进程也是先创建传输控制块TCB,然后向服务器发出连接请求报文,这是报文首部中的同部位SYN=1,同时选择一个初始序列号 seq=x ,此时,TCP客户端进程进入了 SYN-SENT 同步已发送状态
  • 第二次握手 TCP服务器收到请求报文后,如果同意连接,则会向客户端发出确认报文。确认报文中应该 ACK=1,SYN=1,确认号是ack=x+1,同时也要为自己初始化一个序列号 seq=y,此时,TCP服务器进程进入了 SYN-RCVD 同步收到状态.
  • 第三次握手 TCP客户端收到确认后,还要向服务器给出确认。确认报文的ACK=1,ack=y+1,自己的序列号seq=x+1,此时,TCP连接建立,客户端进入ESTABLISHED已建立连接状态 触发三次握手

三次握手主要作用:防止已经失效的连接请求报文突然又传送到了服务器,从而产生错误

第一次握手: 客户端向服务器端发送报文 证明客户端的发送能力正常 第二次握手:服务器端接收到报文并向客户端发送报文 证明服务器端的接收能力、发送能力正常 第三次握手:客户端向服务器发送报文 证明客户端的接收能力正常


TCP四次挥手

建立TCP连接需要三次握手,终止TCP连接需要四次挥手。

张三:好的,那我先走了

李四:好的,那你走吧

李四:那我也走了?

张三:好的,你走吧  

 

Socket的定义

Socket的英文原义是“孔”或“插座”,网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket。

建立网络通信连接至少要一对端口号(socket),socket本质是编程接口(API),对TCP/IP的封装,TCP/IP也要提供可供程序员做网络开发所用的接口,这就是Socket编程接口。

Python 官方关于 Socket 的函数 socket — Low-level networking interface — Python 3.12.4 documentation

Socket的类型  

  • TCP发送数据时,已建立好TCP连接,所以不需要指定地址。UDP是面向无连接的, 每次发送要指定是发给谁。

  • 服务端与客户端不能直接发送列表,元组,字典。需要字节化(data)。

服务端socket函数:

客户端Socket函数

 

共有的函数 :

SOCKET函数描述
s.recv(bufsize[,flag])接受TCP,UDP套接字的数据。数据以字符串形式返回,bufsize指定要接收的最大数据量。
s.send(string[,flag])发送TCP,UDP数据。
s.sendall(string[,flag])完整发送TCP数据。
s.recvfrom(bufsize[.flag])接受UDP套接字的数据。与recv()类似,但返回值是(data,address)。
s.sendto(string[,flag],address)发送UDP数据。将数据发送到套接字,address是形式为(ipaddr,port)的元组,指定远程地址。
s.close()关闭套接字。
s.getpeername()返回连接套接字的远程地址。返回值通常是元组(ipaddr,port)。
s.getsockname()返回套接字自己的地址。
s.setsockopt(level,optname,value)设置给定套接字选项的值。
s.getsockopt(level,optname[.buflen])设置给定套接字选项的值。
s.settimeout(timeout)设置套接字操作的超时期
s.gettimeout()返回当前超时期的值,单位是秒,如果没有设置超时期,则返回None。
s.fileno()返回套接字的文件描述符。
s.setblocking(flag)如果flag为0,则将套接字设为非阻塞模式,否则将套接字设为阻塞模式(默认值)。
s.makefile()创建一个与该套接字相关连的文件

TCP实现一对一的简单聊天

服务端代码:

from socket import *tcp_server = socket(AF_INET, SOCK_STREAM)# 绑定本地信息,TCP服务器程序监听所有网络接口上的88888端口
host_port = ('', 88888)  
tcp_server.bind(host_port)# 使用socket创建的套接字默认的属性是主动的,使用listen将其变为被动的,这样就可以接收别人的链接了
tcp_server.listen(5)while True:newSocket, host_port = tcp_server.accept()while True:# 最大接收1024个字节recvData = newSocket.recv(1024)if len(recvData) > 0:print('recv:', recvData)else:breaksendData = input("send:")newSocket.send(sendData.encode('utf8'))newSocket.close()tcp_server.close()

客户端代码:

from socket import *tcp_client = socket(AF_INET, SOCK_STREAM)# 链接服务器
host_port = ('127.0.0.1', 88888)
tcp_client.connect(host_port)while True:sendData = input("send:")if len(sendData) > 0:tcp_client.send(sendData.encode('utf8'))else:break# 最大接收1024个字节recvData = tcp_client.recv(1024)print('recv:', recvData.decode('uft8'))tcp_client.close()

UDP

UDP ---(User Datagram Protocol) 用户数据报协议,是一个无连接的简单的面向数据报的运输层协议。UDP不提供可靠性,它只是把应用程序传给IP层的数据报发送出去,但是并不能保证它们能到达目的地。由于UDP在传输数据报前不用在客户和服务器之间建立一个连接,没有超时重发等机制,所以传输速度很快。

UDP是一种面向无连接的协议,每个数据报都是一个独立的信息,包括完整的源地址或目的地址,它在网络上以任何可能的路径传往目的地,因此能否到达目的地,到达目的地的时间以及内容的正确性都是不能被保证的。

UDP特点:

UDP是面向无连接的通讯协议,UDP数据包括目的端口号和源端口号信息,由于通讯不需要连接,所以可以实现广播发送。 UDP传输数据时有大小限制,每个被传输的数据报必须限定在64KB之内。 UDP是一个不可靠的协议,发送方所发送的数据报并不一定以相同的次序到达接收方。

【适用情况】 UDP是面向消息的协议,通信时不需要建立连接,数据的传输自然是不可靠的,UDP一般用于多点通信和实时的数据业务,比如

  • 语音广播

  • 视频

  • QQ

  • TFTP(简单文件传送)

  • 大型网络游戏

相比较于TCP注重速度流畅

UDP简单案例

服务端代码

import socketsk = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 绑定 IP 和端口号
sk.bind(('127.0.0.1', 88888))
while True:msg, addr = sk.recvfrom(1024)print('来自[%s:%s]的消息: %s' % (addr[0], addr[1], msg.decode('utf-8')))inp = input('>>>')sk.sendto(inp.encode('utf-8'), addr)sk.close()

 客户端代码:

import socketsk = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
addr = ('127.0.0.1', 88888)
while True:msg = input('>>>')sk.sendto(msg.encode('utf-8'), addr)msg_recv, addr = sk.recvfrom(1024)print(msg_recv.decode('utf-8'))sk.close()

实现简单TFTP(基于UDP协议) 

实现一个简单的TFTP(Trivial File Transfer Protocol)服务器和客户端基于UDP协议是一个有趣的小练习。TFTP是一个简单的文件传输协议,它使用UDP协议,并且通常用于小文件的传输。

我们值实现最基本的功能:从服务器读取文件并发送到客户端。 

TFTP 服务器:

import socket  
import struct  def handle_client(sock, filename):  # 假设文件存在且小于65535字节  try:  with open(filename, 'rb') as file:  data = file.read(512)  # TFTP块大小为512字节  block_number = 1  while data:  # 发送DATA包:block_number + data  block_info = struct.pack('!H', block_number)  # 网络字节序的短整型  sock.sendto(block_info + data, client_address)  # 等待ACK  ack_data, _ = sock.recvfrom(2)  # 只接收block number  ack_block_number = struct.unpack('!H', ack_data)[0]  if ack_block_number != block_number:  print("Incorrect block number in ACK")  break  block_number += 1  data = file.read(512)  except FileNotFoundError:  # 发送ERROR包  error_code = 1  # File not found  error_msg = struct.pack('!HH', error_code, 0)  # TFTP错误消息格式  sock.sendto(error_msg, client_address)  def start_tftp_server(port, root_dir):  server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)  server_socket.bind(('0.0.0.0', port))  print(f"TFTP server listening on port {port}...")  while True:  data, client_address = server_socket.recvfrom(1024)  # 接收RRQ或WRQ请求  # 这里简化处理,只处理RRQ  if data.startswith(b'\x00\x01'):  # RRQ的opcode  filename = data[2:].decode().split(b'\x00')[0]  filepath = f"{root_dir}/{filename}"  handle_client(server_socket, filepath)  if __name__ == "__main__":  start_tftp_server(69, './files') 

TFTP 客户端:

import socket  
import struct  def request_file(server_ip, server_port, filename):  client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)  # 发送RRQ请求  rrq = b'\x00\x01' + filename.encode() + b'\x00' + b'octet' + b'\x00'  # mode为octet  client_socket.sendto(rrq, (server_ip, server_port))  block_number = 0  data = b''  while True:  # 接收DATA包  data_packet, _ = client_socket.recvfrom(514)  # 512字节数据 + 2字节块号  block_number = struct.unpack('!H', data_packet[:2])[0]  if block_number == 0:  # 假设块号为0表示文件结束或错误  break  data += data_packet[2:]  # 发送ACK  ack = struct.pack('!H', block_number)  client_socket.sendto(ack, (server_ip, server_port))  client_socket.close()  # 处理接收到的数据(例如,写入文件)  with open(filename, 'wb') as file:  file.write(data)  if __name__ == "__main__":  request_file('127.0.0.1', 69)file_name = 'example.txt'  request_file(server_addr, 69, file_name)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/48323.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Aouth2单点登录

信息来源B站 不改bug早点睡,北冥 时序图 -----------------------------总结描述 总体流程 浏览器 - 系统1 - 系统2 - 认证中心(SSO) 访问系统1 浏览器,访问系统1,询问认证中心是否登录 未登录,重定向一个登录页面返回给浏…

(二)原生js案例之数码时钟计时

原生js实现的数字时间上下切换显示时间的效果&#xff0c;有参考相关设计&#xff0c;思路比较难&#xff0c;代码其实很简单 效果 代码实现 必要的样式 <style>* {padding: 0;margin: 0;}.content{/* text-align: center; */display: flex;align-items: center;justif…

光盘防水嘛 ? DVD+R 刻录光盘泡水实验

首发日期 2024-07-20, 以下为原文内容: 同志们好, 欢迎来到 胖喵穷人实验室 ! 这里专注于 低成本, 低难度, 低风险 的 “三低” 小实验. 胖喵穷人实验室 (PM-PLab-E)正式名称: 紫腹巨蚊 (Toxorhynchites gravelyi) 系列穷人 (Poor people) 实验室风险警告: 低风险并不是零风险…

人工智能与语音识别:技术进步与应用前景

引言 人工智能&#xff08;AI&#xff09;作为当今科技进步的核心驱动力&#xff0c;正在各个领域展现其变革力量。其中&#xff0c;语音识别技术作为人工智能的重要应用之一&#xff0c;已经深入到我们的日常生活和工作中。从智能助手如Siri、Google Assistant&#xff0c;到智…

kubernetes k8s Deployment 控制器配置管理 k8s 红蓝部署 金丝雀发布

目录 1、Deployment控制器&#xff1a;概念、原理解读 1.1 Deployment概述 1.2 Deployment工作原理&#xff1a;如何管理rs和Pod&#xff1f; 2、Deployment资源清单文件编写技巧 3、Deployment使用案例&#xff1a;创建一个web站点 4、Deployment管理pod&#xff1a;扩…

科研绘图系列:R语言雨云图(Raincloud plot)

介绍 雨云图(Raincloud plot)是一种数据可视化工具,它结合了多种数据展示方式,旨在提供对数据集的全面了解。雨云图通常包括以下几个部分: 密度图(Density plot):表示数据的分布情况,密度图的曲线可以展示数据在不同数值区间的密度。箱线图(Box plot):显示数据的中…

模型剪枝入门

一、定义 1.定义 2. 案例1 3. 全局剪枝案例 4. 全局剪枝案例 5. 自定义剪枝 6. 特定网络剪枝 7. 多参数模块剪枝 8. torch.nn.utils.prune 解读 二、实现 定义 接口&#xff1a; import torch.nn.utils.prune as prune案例1 import torch.nn as nn import torch.nn.utils.…

全部由1组成的子矩形的数量

题目描述&#xff1a; 给定一个二维数组matrix&#xff0c;其中的值不是0就是1&#xff0c;返回全部由1组成的子矩阵的数量。 way&#xff1a; 假设我们遍历矩形的每一行&#xff0c;以当前遍历到的行作为地基&#xff0c;去看这一行的直方图&#xff08;直方图介绍 ->直方…

10.3.3 QGIS点类型注释(Annotation)的应用与二次开发实现

文章目录 前言注释(Annotation)图层QGis中的注释(Annotation)图层二次开发实现线段类型注释(Annotation)点类型Item 总结 前言 介绍注释(Annotation)图层在QGis中的使用以及二次开发的实现说明&#xff1a;文章中的示例代码均来自开源项目qgis_cpp_api_apps 注释(Annotation)…

【Unity实战100例】Unity声音可视化多种显示效果

目录 一、技术背景 二、界面搭建 三、 实现 UIAudioVisualizer 基类 四、实现 AudioSampler 类 五、实现 IAudioSample 接口 六、实现MusicAudioVisualizer 七、实现 MicrophoneAudioManager 类 八、实现 MicrophoneAudioVisualizer 类 九、源码下载 Unity声音可视化四…

代码随想录算法训练营第九天 |LeetCode151.翻转字符串里的单词 卡码网:55.右旋转字符串

代码随想录算法训练营 Day 9 代码随想录算法训练营第九天 |LeetCode151.翻转字符串里的单词 卡码网&#xff1a;55.右旋转字符串 目录 代码随想录算法训练营前言LeetCode151.翻转字符串里的单词卡码网&#xff1a;55.右旋转字符串 一、LeetCode151.翻转字符串里的单词1.题目链…

laravel为Model设置全局作用域

如果一个项目中存在这么一个sql条件在任何情况下或大多数情况都会被使用&#xff0c;同时很容易被开发者遗忘&#xff0c;那么就非常适用于今天要提到的这个功能&#xff0c;Eloquent\Model的全局作用域。 首先看一个示例&#xff0c;有个数据表&#xff0c;结构如下&#xff1…

一款国外开发的高质量WordPress下载站模板主题

5play下载站是由国外站长开发的一款WordPress主题&#xff0c;主题简约大方&#xff0c;为v1.8版本&#xff0c; 该主题模板中包含了上千个应用&#xff0c;登录后台以后只需要简单的三个步骤就可以轻松发布apk文章&#xff0c; 我们只需要在WordPress后台中导入该主题就可以…

大模型应用如何点燃?

▎****尽管在中国&#xff0c;关于大模型的商业模式的讨论尚显早期&#xff0c;但智能体&#xff0c;尤其是专业智能体&#xff0c;蕴藏着巨大的潜力。 ChatGPT 还没有颠覆世界。 身处“第三次信息革命”&#xff0c;很多人被浓烈的FOMO&#xff08;Fear of Missing Out&…

昇思25天学习打卡营第12天 | ResNet50图像分类

ResNet50在CIFAR-10数据集上的图像分类实践 在深入学习和实践使用ResNet50进行CIFAR-10数据集上的图像分类后&#xff0c;我对深度学习模型的构建、训练和优化有了更深刻的理解。本次学习经历涵盖了从理论探索到实际应用的全过程&#xff0c;以下是我的主要收获和反思。 1. 理…

(南京观海微电子)——电感的电路原理及应用区别

电感 电感是导线内通过交流电流时&#xff0c;在导线的内部及其周围产生交变磁通&#xff0c;导线的磁通量与生产此磁通的电流之比。 当电感中通过直流电流时&#xff0c;其周围只呈现固定的磁力线&#xff0c;不随时间而变化&#xff1b;可是当在线圈中通过交流电流时&am…

Jump Point Search(JPS)算法与A*算法

A* A*算法本质上讲是结合了DFS和BFS&#xff0c;针对当前起点先做一次BFS&#xff0c;再针对搜索的八个点做一次DFS BFS--广度优先算法&#xff08;Breadth First Search&#xff09; DFS A* 算法思想 A*的核心思想就是先进行一次BFS搜索&#xff0c;然后从这次BFS中找到距离…

python Requests库7种主要方法及13个控制参数(实例实验)

文章目录 一、Requests库的7种主要方法二、kwargs:控制访问的13个参数 一、Requests库的7种主要方法 序号方法说明1requests.request()&#xff1a;提交一个request请求&#xff0c;作为其他请求的基础2requests.get()&#xff1a;获取HTML网页代码的方法3requests.head()&…

基于重要抽样的主动学习不平衡分类方法ALIS

这篇论文讨论了数据分布不平衡对分类器性能造成的影响,并提出了一种新的有效解决方案 - 主动学习框架ALIS。 1、数据分布不平衡会影响分类器的学习性能。现有的方法主要集中在过采样少数类或欠采样多数类,但往往只采用单一的采样技术,无法有效解决严重的类别不平衡问题。 2、论…

9种二极管及其特点总结

二极管种类和特点 名字特点恒流二极管近些年出现&#xff0c;电压大于某个值&#xff0c;电流恒定&#xff0c;一般用于led普通二极管低频整流和续流&#xff0c;便宜&#xff0c;反向恢复时间us级别&#xff0c;PN结肖特基二极管比普通二极管反向关断更快&#xff0c;10ns级别…