为什么TCP套接字用四元组标识而UDP是二元组?
我们知道TCP和UDP是使用不同的套接字标识符来实现分用和复用,TCP使用四元组(源IP,源端口,目标IP,目标端口)来标识一个TCP套接字,而UDP使用的是二元组(目的ip,目标端口)来标识。
在这里我们不妨思考一个问题,为什么TCP要用四元组来标识,而UDP使用二元组呢。
假设TCP使用的是二元组来区别不同的TCP套接字,那么会出现什么情况呢?
1,显然使用(目的ip,目标端口)这种二元组的情况并不能唯一标识这个socket
首先,我们知道TCP是面向连接的传输协议,对于每一个建立的连接都会在TCP服务端有一个对应的socket来管理这个连接(原本这是个四元组标识这个socket),因为可能存在这样一种情况: 由多个访问同一台服务器的客户端发起TCP连接的目的ip一致,目标端口也一致,因为没有源ip和源端口,所以服务端无法知道TCP缓冲区中的多个包分别来自哪个源主机,从而导致无法拆包。这就解释了为什么TCP套接字要使用四元组而不是二元组了。
2,使用二元组无法解决粘包问题,why?
其次,TCP和UDP是不同的,TCP是流式协议,UDP是数据报协议,他们内部实现的机制很大不同。表现在工程实践中就是TCP有粘包的问题,而UDP没有,它有消息边界。
产生粘包的几种情况:
(1)TCP粘包是因为当我们使用send的时候,并不会马上发送,为了网络优化,系统内核会将消息写入发送的缓冲区中,当时钟超时或者缓冲区满的时候才会打包发送,这就会发生多次发送的数据在打包在一个报文中产生粘包现象,
(2)另外在接收方收到的数据都会缓存在接收缓冲区中,这样同样会导致收取的时候有粘包现象,在使用四元组标识tcp的时候,粘包问题可以通过拆包来解决。
但是:
由此可以想象,如果TCP使用的是二元组会导致什么现象,不同的具备相同源端口的用户,所产生的数据包会经由同一个socket,因为标识相同,无法区分哪个包属于哪台主机,那么这时产生的粘包就无法解决。而UDP是数据报协议,它会尽快将上层应用的信息立刻打包并发送(无需发送缓冲区),而服务端每次读取一个数据包。这就解释为什么UDP不会产生粘包的问题。
为什么TCP套接字用四元组标识而UDP是二元组?相关推荐
- 《计算机网络:自顶向下方法(原书第6版)》一2.7 TCP套接字编程
本节书摘来华章计算机<计算机网络:自顶向下方法(原书第6版)>一书中的第2章 ,第2.7节,(美)James F.Kurose Keith W.Ross 著 陈 鸣 译 更多章节内容可以访 ...
- 第2章 基本的TCP套接字
2.1 IPv4 TCP客户端 4个步骤: (1) socket()创建TCP套接字(window下要用初始化套接字环境) (2) connect()建立到达服务起的连接 (3) send() ...
- (十三) 深入浅出TCPIP之TCP套接字参数
专栏其他文章: 理论篇: (一)深入浅出TCPIP之理解TCP报文格式和交互流程 (二)深入浅出TCPIP之再识TCP,理解TCP三次握手(上) (三)深入浅出TCPIP之再识TCP,理解TCP四次挥 ...
- 构建TCP套接字(socket)的概念及具体步骤
首先要说一下socket套接字的基本定义以及概念,这里先列举微软计算机词典对于套接字的描述 Socket is an identifier for a particular service on a ...
- TCP套接字编程详解
目录 为什么socket编程又叫套接字编程? TCP服务端 初始化套接字库--WSAStarup 创建套接字--socket 绑定到本机 --bind 开始监听 --listen 连接客户端请求--a ...
- 计算机网络(二) | 网络编程基础、Socket套接字、UDP和TCP套接字编程
目录 一.网络编程基础 1.1 为什么需要网络编程 1.2 什么是网络编程 1.3 网络编程中的基本概念 二.Socket套接字 2.1 概念 2.2 分类 2.3 Java数据报套接字通信模型 2. ...
- 专题 15 TCP套接字编程
概述 存在三种套接字:流式套接字(SOCK_STREAM).数据报套接字(SOCK_DGRAM)和原始套接字(SOCK_RAW). TCP套接字工作流程: 首先,服务器端启动进程,调用Socket创建 ...
- 【UNIX网络编程(二)】基本TCP套接字编程函数
基于TCP客户/server程序的套接字函数图例如以下: 运行网络I/O.一个进程必须做的第一件事就是调用socket函数.指定期望的通信协议类型. #include <sys/socket.h ...
- Python之路(第三十一篇) 网络编程:简单的tcp套接字通信、粘包现象
一.简单的tcp套接字通信 套接字通信的一般流程 服务端 server = socket() #创建服务器套接字server.bind() #把地址绑定到套接字,网络地址加端口server.liste ...
最新文章
- linux常用快捷命令(不断更新)
- cannot import name 'ImageRecordInt8Iter'
- 华为鸿蒙系统支持智慧多屏吗,搭载鸿蒙OS!华为宣布企业智慧屏:多屏协同、底座带轮子...
- 怎样新建Oracle数据库
- oracle语句怎么倒退,oracle RETURNING 子句使用方法
- python插件使用教程_Python常用扩展插件使用教程解析
- c语言分配多一个字符空间,关于C语言动态给字符串分配内存空间问题
- 【转载】jvm内存回收
- 分享 :用五个趣味案例教你数据分析的基本思想
- 极光IM使用教程-极光推送
- Linux下PHP5.5编译参数详解
- 计算机组成原理之模2运算
- 魔百盒 UNT403A UNT413A S905L3A卡刷精简固--S905L3A
- 跨境电商ERP系统功能有那些?
- 学长教你买电脑(笔记本篇)
- JDK8绿色安装详细步骤
- 2021年茶艺师(初级)证考试及茶艺师(初级)理论考试
- opencv3_java 图像的修剪裁剪Trimming Rect
- 基于opencv的MTF算法开发
- 逆反西游无法读取服务器信息,逆反西游
热门文章
- pytest文档48-切换 base_url 测试环境(pytest-base-url)
- github 加速(基于gitee)
- Linux 解压缩文件之zip命令
- 并查集(python代码实现)
- 【C语言】C语言外部变量和内部变量
- 来自GitHub的系列渗透测试工具
- 错误收集:备忘MPI Application rank 0 exited before MPI_Finalize()nbsp
- 旷视全新智能人像抓拍机:1080P高清视频格式,抓拍率不低于98%。
- 计算机软件水平考试题,计算机程序员软件水平考试试题
- TIM 默认存储文件夹修改不成功