网络编程——wireshark抓包、tcp粘包

news2024/9/19 10:45:59

目录

一、前言

1.1 什么是粘包

1.2 为什么UDP不会粘包

二、编写程序

文件树

客户端程序

服务器程序 

 tcp程序

头文件 

 makefile

三、 实验现象 

四、改进实验

五、小作业


一、前言

        最近在做网络芯片的驱动,验证功能的时候需要借助wireshark这个工具,今天就来回顾下网络编程相关的知识。

1.1 什么是粘包

        在网络通信过程中,数据包往往是连续发送的,尤其是在稳定且高速的网络连接中。这种连续传输可以提高数据传输的效率,减少因等待发送或接收数据包而产生的延迟。

        在TCP/IP协议中,由于TCP是一个面向连接的、可靠的、基于字节流的传输层通信协议,它不保留消息边界。这意味着在发送端连续发送的多个数据包,在接收端可能会被合并成一个大的数据包接收(粘包),或者一个完整的数据包被拆分成多个小数据包接收(拆包)。

|eth header|IP header|tcp header| data |
[12 bytes] | 20 bytes| 20 bytes |"abc" |
                                   |
                              data只占4个字节,
    而为了发送这4个字节,需要12+20+20,至少52个字节,会造成极大的资源浪费

1.2 为什么UDP不会粘包

  1. 独立的传输机制:由于UDP数据报的独立性,每个数据报都是单独发送和接收的,不会与其他数据报混合在一起。因此,在接收端,每个UDP数据报都可以被清晰地识别和处理,不会出现TCP中可能遇到的粘包问题。
  2. 没有面向连接的数据流:UDP不像TCP那样提供面向连接的数据流服务。TCP为了保证数据的可靠传输,会对数据进行拆分、重排和合并等操作,这些操作可能会导致粘包现象。而UDP则没有这些操作,它直接发送和接收完整的数据报,因此不会出现粘包问题。
  3. 基于数据报的传输模式:UDP的传输模式是基于数据报的,即每个数据报都是一个完整的单元,具有独立的传输路径和生命周期。这种传输模式使得UDP能够避免TCP中可能出现的粘包和拆包问题。

了解了以上概念我们开始验证这个问题。

二、编写程序

文件树

这是我们的目录结构分为服务器和客户端 

客户端程序

#include "tcp.h"

int main(int argc, char *argv[])
{
	int fd;
	int ret, i = 2;
	char buf[BUFSIZ] = {"===test===\n"};
	/*检查参数*/
	Argment(argc, argv);

	fd = SocketInit(argv, false);

	/*发送数据*/
	while(i--){
		do {
			ret = send(fd, buf, strlen(buf), 0);
		}while(ret < 0 && errno == EINTR); //如果信号导致的错误,继续执行
		if(ret < 0)
			ErrExit("recv");
		else if(!ret)
			break;
		printf("send data:%s", buf);
		fflush(stdout);
	}

	close(fd);
	return 0;
}

我们进行两次连发看看效果是什么样的 

服务器程序 

#include "tcp.h"

int main(int argc, char *argv[])
{
	int fd, newfd;
	int ret;
	char buf[BUFSIZ];
	Addr_in client_addr;
	socklen_t addrlen = sizeof(Addr_in);
	/*检查参数*/
	Argment(argc, argv);
	/*创建服务端套接字*/
	fd = SocketInit(argv, true);

	/*接收客户端连接*/
	do {
		newfd = accept(fd, (Addr *)&client_addr, &addrlen);
	}while(newfd < 0 && errno == EINTR); //如果信号导致的错误,继续执行
	if(newfd < 0)
		ErrExit("accept");

	/*接收客户端数据*/
	while(1){
		do {
			ret = recv(newfd, buf, BUFSIZ, 0);
		}while(ret < 0 && errno == EINTR); //如果信号导致的错误,继续执行
		if(ret < 0)
			ErrExit("recv");
		else if(!ret)
			break;
		else
			printf("[%s:%d]buf:%s\n", 
					inet_ntoa(client_addr.sin_addr), 
					ntohs(client_addr.sin_port), buf);
		printf("getchar()\n");
		getchar();
	}

	close(newfd);
	close(fd);
	return 0;
}

 tcp程序

#include "tcp.h"

void Argment(int argc, char *argv[]){
	if(argc < 3){
		fprintf(stderr, "%s <addr><port>\n", argv[0]);
		exit(EXIT_FAILURE);
	}
}

int SocketInit(char *argv[], bool server){
	int fd;
	Addr_in addr;
	func_t func = server?bind:connect;
	/*创建套接字*/
	if( (fd = socket(AF_INET, SOCK_STREAM, 0) ) < 0)
		ErrExit("socket");
	/*设置通信结构体*/
	bzero(&addr, sizeof(addr) );
	addr.sin_family = AF_INET;
	addr.sin_port = htons( atoi(argv[2]) );
	if (inet_aton(argv[1], &addr.sin_addr) == 0) {
		fprintf(stderr, "Invalid address\n");
		exit(EXIT_FAILURE);
	}

	/*地址快速重用*/
	int b_reuse = 1;
	setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &b_reuse, sizeof(int) );

	/*发起连接请求或绑定地址*/
	if( func(fd, (Addr *)&addr, sizeof(addr) ) )
		ErrExit("connect or bind");

	if(server){
		/*监听模式*/
		if( listen(fd, BACKLOG) )
			ErrExit("listen");

	}
	return fd;
}

头文件 

#ifndef _TCP_H_
#define _TCP_H_

#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <stdlib.h>
#include <unistd.h>
#include <strings.h>
#include <arpa/inet.h>
#include <errno.h>
#include <stdbool.h>
#include <string.h>

#define BACKLOG 5

#define ErrExit(msg) do { perror(msg); \
	exit(EXIT_FAILURE); } while(0)


typedef struct sockaddr Addr;
typedef struct sockaddr_in Addr_in;

typedef int (* func_t)(int, const Addr *, socklen_t);

void Argment(int argc, char *argv[]);
int SocketInit(char *argv[], bool server);
#endif

 makefile


all:server client
CC=gcc
CFLAGS=-g -Wall

server:tcp.c server.c

client:tcp.c client.c

clean:
	rm server client

三、 实验现象 

在ubuntu22.04和ubuntu18.04上都能实现。 

但是发现有个问题

还有发两次的现象

四、改进实验

 先ping下百度,看看百度的ip是多少

#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <unistd.h>

int main(int argc, const char *argv[])
{
	int fd = socket(AF_INET, SOCK_STREAM, 0);
	struct sockaddr_in sin = {
		.sin_family = AF_INET,
		.sin_port = htons(80),
	};
	if (inet_aton("110.242.68.66", &sin.sin_addr) == 0) {
		fprintf(stderr, "Invalid address\n");
		exit(EXIT_FAILURE);
	}

	if(connect(fd, (struct sockaddr *)&sin, sizeof(sin) ) < 0) {
		perror("connect");
		exit(0);
	}

	send(fd, "hello", 5, 0);
	send(fd, "hello", 5, 0);
	send(fd, "hello", 5, 0);
	send(fd, "hello", 5, 0);
	send(fd, "hello", 5, 0);
	send(fd, "hello", 5, 0);

	close(fd);

	return 0;
}

写完程序后运行wireshark

选择上互联网用的网卡 

 

       我们会发现6个hello被划分到了两个包里一个1个hello另一个5个,但是我们用了6次send正常应该6个包的,这就是粘包现象。 

注意:PSH代表有数据包,FIN代表没有数据包了

五、小作业

兄弟们可以试试分包现象的验证,搞一个大的包看看是不是会被分开。

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

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

相关文章

DataX(二):DataX安装与入门

1. 官方地址 下载地址&#xff1a;http://datax-opensource.oss-cn-hangzhou.aliyuncs.com/datax.tar.gz 源码地址&#xff1a;GitHub - alibaba/DataX: DataX是阿里云DataWorks数据集成的开源版本。 2. 前置要求 Linux JDK(1.8 以上&#xff0c;推荐 1.8) Python(推荐 Pyt…

C语言内存函数精讲

目录 引言 1.内存分配函数malloc 2.内存释放函数free 3.内存拷贝函数memcpy 4.内存移动函数memmove 5.内存设置函数memset 6.内存比较函数memcmp 总结 引言 在C语言编程中&#xff0c;内存管理是核心技能之一。C语言提供了一系列内存操作函数&#xff0c;这些函数在动…

机器学习 第7章-贝叶斯分类器

机器学习 第7章-贝叶斯分类器 7.1 贝叶斯决策论 贝叶斯决策论(Bayesian decision theory)是概率框架下实施决策的基本方法。对分类任务来说&#xff0c;在所有相关概率都已知的理想情形下&#xff0c;贝叶斯决策论考虑如何基于这些概率和误判损失来选择最优的类别标记。下面我…

Linux Vim全能攻略:实战代码,轻松掌握文本编辑神器

1. Vim简介与安装 1.1 Vim的历史与发展 Vim&#xff08;Vi IMproved&#xff09;是一款高度可配置的文本编辑器&#xff0c;它起源于1976年由Bill Joy开发的Vi编辑器。Vi是Unix系统上最古老的文本编辑器之一&#xff0c;因其强大的功能和高效的编辑方式而广受欢迎。随着时间的…

流媒体服务器一:搭建RTMP流媒体服务器搭建

1 安装和测试srs流媒体服务器 服务器&#xff1a;SRS(Simple RTMP Server&#xff0c;⽀持RTMP、HTTP-FLV&#xff0c;HLS) 推流端&#xff1a;ffmpeg OBS 拉流端&#xff1a;ffplay VLC srs播放器 1.1 安装srs流媒体服务器 官网 SRS (Simple Realtime Server) | SRS 码…

【一图流】Git下载与安装教程

下载Git Git官网&#xff1a;https://git-scm.com/?hlzh-cn 安装Git

全栈嵌入式C++、STM32、Modbus、FreeRTOS和MQTT协议:工业物联网(IIoT)可视化系统设计思路(附部分代码解析)

项目概述 随着工业4.0时代的到来&#xff0c;工业物联网&#xff08;IIoT&#xff09;在提高生产效率、降低运营成本和实现智能制造方面得到了广泛应用。本项目旨在开发一个全面的工业物联网监控系统&#xff0c;能够实时监测设备的温度、压力、振动和电流等参数&#xff0c;并…

浅析Jeecgboot中mybatisplus不支持Postgres SKIP LOCKED语法问题

目录 1、场景及问题 2、数据库及各框架版本信息 3、错误回放 4、根因分析及确认 5、解决问题 6、总结 1、场景及问题 场景&#xff1a; 在调用腾讯位置服务时有用到key值&#xff0c;因为每个key值都有自己的额度&#xff0c;所以在表里存了多个key&#xff0c;简称key池&…

基于Java的城市公交管理系统/SSM的城市公交查询系统/计算机专业/课设

摘 要 网络技术的不断发展&#xff0c;使网络成为人们的日常生活中不可缺少的一部分&#xff0c;而城市公交管理系统是网络的一种新型体现&#xff0c;它以其特有的便捷和快速的特点得到了广泛的认可。当前的城市公交管理系统不仅没有建立起整体的管理系统&#xff0c;为企业定…

Go语言中常见的多线程同步方法

什么是线程、进程、协程 Go 源文件经过编译器处理后&#xff0c;会产生可执行文件&#xff0c;不同系统有不同的格式。可执行文件在操作系统上执行一次&#xff0c;就对应一个进程 进程可以理解为执行中的程序&#xff0c;是一个动态的概念&#xff0c;同一份可执行文件执行多…

Django 表单error_messages , 表单校验提示

在Django中&#xff0c;error_messages是表单字段的一个参数&#xff0c;允许你为特定的验证错误自定义错误消息。默认情况下&#xff0c;Django的表单字段会为常见的验证错误提供默认的错误消息。但是&#xff0c;你可能想要为你的应用提供更加用户友好的或者本地化的错误消息…

成为git砖家(2): gitk 介绍

大家好&#xff0c;我是白鱼。这篇我们介绍 gitk。 gitk 和 fork 界面对比 当我们在 macOS 上执行 brew install git 后&#xff0c; 得到了 git 命令行工具。 然而这条命令并不会安装 gitk. gitk 是 git 自带的图形化界面工具&#xff0c;也可以称为“穷人版 fork”&#xf…

如何穿透模糊,还原图片真实面貌

目录 图像清晰化的魔法棒&#xff1a;AI如何穿透模糊&#xff0c;还原图片真实面貌 前言 论文背景 论文思路 模型介绍 复现过程 演示视频 使用方式 本文所涉及所有资源均在传知代码平台可获取。 图像清晰化的魔法棒&#xff1a;AI如何穿透模糊&#xff0c;还原图片真实面貌 在我…

使用Docker搭建MySql的主从同步+ShardingSphere搭建Mysql的读写分离

参考课程 尚硅谷ShardingSphere5实战教程&#xff08;快速入门掌握核心&#xff09;_哔哩哔哩_bilibili 主服务器 创建容器 docker run -d \ -p 3306:3306 \ -v /kira/mysql/master/conf:/etc/mysql/conf.d \ -v /kira/mysql/master/data:/var/lib/mysql \ -e MYSQL_ROOT…

java学习---异常

前言 由于被分母不能为0&#xff0c;所以代码到int yn/m;会抛出异常&#xff0c;停止运行下去&#xff0c;但是如果是个庞大的代码&#xff0c;因为这种小错误而整个程序崩溃&#xff0c;会大大影响代码整体的健壮性&#xff0c;所以此时就需要我们得异常处理了 选中异常代码部…

正则采集器——前端搭建

前端使用有名的饿了么管理后台&#xff0c;vue3版本vue3-element-admin&#xff0c;首先从gitee中克隆一个vue3-element-admin模板代码vue3-element-admin: Vue3 Element Admin开箱即用的中后台管理系统前端解决方案&#xff0c;然后在此基础上进行开发。 1、修改vite.config.…

【深入理解SpringCloud微服务】深入理解Ribbon原理并手写一个微服务负载均衡器

深入理解Ribbon原理并手写一个微服务负载均衡器 负载均衡器理解Ribbon原理手写一个微服务负载均衡器总体设计LoadBalanceClientHttpRequestFactorySimpleLoadBalanceClientSimpleLoadBalancerLoadBalanceRulespring.factories与LoadBalanceConfig 负载均衡器 在微服务架构里面…

应用层_计算机网络

文章目录 应用层HTTP用户与服务器的交互&#xff1a;cookieWeb缓存HTTP/2 SMTPDNS&#xff1a;因特网的目录服务P2P文件分发BitTorrentCDN内容分发网 应用层 应用层协议定义了运行在不同端系统上的应用程序进程如何相互传递报文。应用层协议定义了以下内容&#xff1a; 交换的…

结构性设计模式-外观模式

一、外观模式 有些人可能炒过股票&#xff0c;但其实大部分人都不太懂&#xff0c;这种没有足够了解证券知识的情况下做股票是很容易亏钱的&#xff0c;刚开始炒股肯定都会想&#xff0c;如果有个懂行的帮帮手就好&#xff0c;其实基金就是个好帮手&#xff0c;支付宝里就有许…

算力共享:如何理解、标识与调控多层次算力资源的异构性和复杂性,实现智能算力网生态诸要素有效互操作?

目录 鹏程云主机和NPU计算服务器关系 NPU计算服务器 两者关系 结论 两种不同类型的处理器或计算单元 FPGA MLU NS3(Network Simulator version 3) 一、基本属性 二、主要功能与特点 三、应用与前景 对象存储和HDD存储 一、定义与特点 二、应用场景 三、总结 对…