网络编程 day2

题目

代码

服务器

typedef char DataType[32];	//普通节点数据类型

typedef struct NODE
{
	union
	{
		DataType data;	//普通节点数据域
		int len;			//头节点数据域
	};
	struct NODE *next;		//指针域
}node,*nodePtr;

struct PACK
{
	int size;	//告知 通信传输的数据的大小
	int type;	//决定对数据如何操作
	char buf[1500];	//数据
	int count;	//用于记录 已经 读取/写入 到数据的什么位置
};

//创建头节点
nodePtr creatList(void);
//申请节点 封装数据
nodePtr malloc_newnode(DataType e);
//添加数据
void add_data(nodePtr H,DataType e);
//解析数
nodePtr unlood(nodePtr H,struct PACK packPtr);
//显示数据
void showdata(nodePtr H);


int main(int argc, const char *argv[])
{
	//创建套接字
	int serverfd=socket(AF_INET,SOCK_STREAM,0);	//ipv4 tcp形式 自动选择协议
	//ip地址 和 potr端口号 放入"网络通信结构体"
	struct sockaddr_in addr;
	addr.sin_family=AF_INET;	//ipv4
	int port=atoi(argv[1]);
	addr.sin_port=htons(port);	//端口号 (大端存储)
	addr.sin_addr.s_addr=inet_addr("0.0.0.0");	//ip地址
	//结构体数据 写入 套接字
	int res=bind(serverfd,(struct sockaddr*)&addr,sizeof(addr));
	if(res==-1)
	{
		printf("套接字 创建失败\n");
		perror("bind");
		return 0;
	}
	printf("套接字 创建成功\n");
	//监听
	listen(serverfd,10);
	//接受链接
	struct sockaddr_in client_addr;		//创建"网络信息结构体" 用于接受客户端消息
	int client_addr_len=sizeof(client_addr);	//长度
	int clientfd=accept(serverfd,(struct sockaddr *)&client_addr,&client_addr_len);

	printf("链接到客户端\n");
	nodePtr H=creatList();	//创建头节点
	if(NULL==H){return 0;}
	//读取数据
	while(1)
	{
		//创建 网络通信结构体
		struct PACK pack;
		pack.count=0;	//读写位置 初始化为0
		int res=read(clientfd,&pack.size,4);
		if(res==0){break;}

		res=read(clientfd,(char *)&pack+4,pack.size-4);
		if(res==0){break;}
		//解析数据
		unlood(H,pack);
		//显示数据
		showdata(H);
	}
	return 0;
}

nodePtr creatList(void)
{
	nodePtr H=(nodePtr)malloc(sizeof(node));
	if(NULL==H)
	{
		printf("节点申请失败\n");
		return NULL;
	}
	//头节点 指针域处理
	H->next=NULL;
	//头节点 数据域处理
	H->len=0;
	return H;
}

//申请节点 封装数据
nodePtr malloc_newnode(DataType e)
{
	nodePtr newnode=(nodePtr)malloc(sizeof(node));
	if(NULL==newnode)
	{
		printf("节点申请失败\n");
		return NULL;
	}
	//指针域 处理
	newnode->next=NULL;
	//数据域 处理
	memcpy(newnode->data,e,sizeof(DataType));
	return newnode; 
}
void add_data(nodePtr H,DataType e)
{
	nodePtr newnode=malloc_newnode(e);
	if(NULL==newnode)
	{
		printf("普通节点申请失败 或 数据放入链表失败\n");
		return;
	}
	nodePtr temp=H;
	while(temp->next!=NULL)
	{
		temp=temp->next;	//成为下一个节点
	}
	//最后一个节点 指向本节点
	temp->next=newnode;
	//链表长度增加
	H->len++;
}


nodePtr unlood(nodePtr H,struct PACK packPtr)
{
	if(NULL==H)
	{
		printf("地址不合法");
		return NULL;
	}
	
	while(1)
	{
		//获取数据长度
		int len=*(short *)(packPtr.buf+packPtr.count);
		if(len==0)
		{
			printf("数据解析完毕\n\n");
			return H;
		}
		packPtr.count+=2;
		//读取字符串数据 写入到buf
		DataType e={0};
		memcpy(e,packPtr.buf+packPtr.count,len);
		add_data(H,e);
		packPtr.count+=len;
	}
}


void showdata(nodePtr H)
{
	if(NULL==H)
	{
		printf("链表地址不合法\n");
		return;
	}
	if(H->len==0)
	{
		printf("链表数据为空\n");
		return;
	}
	nodePtr temp=H;
	while(temp->next!=NULL)
	{
		temp=temp->next;	//成为下一个节点
		printf("data=%s\n",temp->data);	//输出显示数据
	}
	printf("链表数据 显示完毕\n");
}

客户端

struct PACK
{
	int size;	//数据包大小
	int type;	//对数据的操作
	char buf[1500];	//数据
	int conut;	//数据已经占用多少字节
};

//数据附加 放入数据
void append(struct PACK* pack,const char *data);

int main(int argc, const char *argv[])
{
	//创建套接字
	int clientfd=socket(AF_INET,SOCK_STREAM,0);	//ipv4 tcp形式 自动选择协议
	//ip地址 和 potr端口号 放入"网络通信结构体"
	struct sockaddr_in addr;
	addr.sin_family=AF_INET;	//ipv4
	int port=atoi(argv[1]);
	addr.sin_port=htons(port);	//端口号
	addr.sin_addr.s_addr=inet_addr("192.168.93.128");	//服务器ip地址

	//结构体数据 写入 套接字
	int res=connect(clientfd,(struct sockaddr*)&addr,sizeof(addr));
	if(res==-1)
	{
		printf("套接字 创建失败\n");
		perror("bind");
		return 0;
	}

	//发送
	struct PACK pack;
	pack.conut=0;
	while(1)
	{
		char buf[20];
		printf("请输入 用户:");
		scanf("%19s",buf);
		while(getchar()!=10);
		append(&pack,buf);

		printf("请输入 密码:");
		scanf("%19s",buf);
		while(getchar()!=10);
		append(&pack,buf);

		pack.size=pack.conut+8;	//包实际大小
		write(clientfd,&pack,pack.size);		//发送给服务器 将接受多少字节
		pack.conut=0;	//发送完毕 conut 重置
	}

	return 0;
}

//数据附加 放入数据
void append(struct PACK* pack,const char *data)
{

	int len=strlen(data);
	*(short *)(pack->buf+pack->conut)=len;
	pack->conut+=2;
	memcpy(pack->buf+pack->conut,data,len);
	pack->conut+=len;
}

效果

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【鸿蒙HarmonyOS Next实战开发】实现ArkTS/JS和C/C++的交互-Node-API

一、HarmonyOS Node-API简介 在HarmonyOS应用开发中,通常以ArkTS/JS语言为主,但在一些特殊场景下,例如游戏开发、物理模拟等,由于对性能、效率等有较高要求,需要借助现有的C/C库来实现。为了满足这种需求,…

Postgresql的三种备份方式_postgresql备份

这种方式可以在数据库正在使用的时候进行完整一致的备份,并不阻塞其它用户对数据库的访问。它会产生一个脚本文件,里面包含备份开始时,已创建的各种数据库对象的SQL语句和每个表中的数据。可以使用数据库提供的工具pg_dumpall和pg_dump来进行…

51单片机之使用Keil uVision5创建工程以及使用stc-isp进行程序烧录步骤

一、Keil uVision5创建工程步骤 1.点击项目,新建 2.新建目录 3.选择目标机器,直接搜索at89c52选择,然后点击OK 4.是否添加起吊文件,一般选择否 5.再新建的项目工程中添加文件 6.选择C文件 7.在C文件中右键,添加…

基础篇05-直方图操作

本节将简要介绍Halcon中有关图像直方图操作的算子,重点介绍直方图获取和显示两类算子,以及直方图均衡化处理算子。 目录 1. 引言 2. 获取并显示直方图 2.1 获取(灰度)直方图 (1) gray_histogram (2) gray_histo_abs (3) gr…

3.攻防世界 weak_auth

题目描述提示 是一个登录界面,需要密码登录 进入题目页面如下 弱口令密码爆破 用1 or 1 #试试 提示用admin登录 则尝试 用户名admin密码:123456 直接得到flag 常用弱口令密码(可复制) 用户名 admin admin-- admin or -- admin…

金蛇祈福,鸿运开年!广州白云皮具城2025开市大吉!

锣鼓一响,黄金万两!2月6日大年初九,广州白云皮具城举行盛大的醒狮开市仪式!象征吉祥如意的醒狮,将好运、财运传递给全体商户和八方来客。 醒狮点睛 金鼓一响黄金万两,十头醒狮登台,董事总经理刘…

【Axure教程】标签版分级多选下拉列表

分级多选下拉列表是指一个下拉列表,它包含多个层次的选项,用户可以选择一个或多个选项。这些选项通常是根据某种层级关系来组织的,例如从上到下有不同的分类或者过滤条件,用户选择上层选项后,下层选项会发生变化&#…

SpringBoot中的多环境配置管理

SpringBoot中的多环境配置管理 文章目录 SpringBoot中的多环境配置管理SpringBoot中的多环境配置管理 多环境配置的概述1. 为什么需要多环境配置?2. Spring Boot 中如何实现多环境配置?3. 多环境配置的应用场景4. 如何实现配置隔离? Spring B…

SOME/IP报文格式及发现协议详解

在之前的文章中,我们介绍了SOME/IP协议的几种服务接口。在本篇博客中,主要介绍some/ip协议传输的header报文格式以及SOME/IP-SD发现协议。 目录 流程 报文格式 Message ID Length Request ID protocal version/Interface Version Message Type…

使用Ollama本地部署deepseek

1、下载安装Ollama 前往下载页面 https://ollama.com/download下载好安装包,如同安装软件一样,直接安装即可 win中默认为C盘,如果需要修改到其他盘,查找具体教程 运行list命令,检查是否安装成功 2、修改模型下载的…

约束布局属性学习

1、layout_constraintHorizontal_bias layout_constraintHorizontal_bias 是 ConstraintLayout 中的一个重要属性,用于控制一个视图在父视图或相关视图中水平位置的偏移。这种偏移通过在0到1之间的浮点值来设置,0代表完全靠近左边或起始位置&#xff0c…

Windows双网卡冲突导致网页加载过慢的解决方法 (修改跃点无效 远程桌面连接)

【本文发布于https://blog.csdn.net/Stack_/article/details/145494160,未经许可不得转载,转载须注明出处】 办公室内,我的笔记本和台式机都连接WIFI进行上网,网段是192.168.0.x,网关192.168.0.101 现在要通过Windows自…

轻量级服务器http-server

安装 sudo npm install http-server -g 运行 1. 直接去到要跑起来的目录,在终端输入 cd xxxx文件夹http-server //只输入http-server的话,更新了代码后,页面不会同步更新http-server -c-1 //同步更新页面http-server -a 127.0.0.1 -p 808…

代码随想录算法【Day38】

Day38 322. 零钱兑换 思路 完全背包 代码 class Solution { public:int coinChange(vector<int>& coins, int amount) {vector<int> dp(amount 1, INT_MAX);dp[0] 0;for (int i 0; i < coins.size(); i) { // 遍历物品for (int j coins[i]; j <…

python+opencv+open3d实现鼠标手画多边形裁剪分割点云操作

👑主页:吾名招财 👓简介:工科学硕,研究方向机器视觉,爱好较广泛… ​💫签名:面朝大海,春暖花开! python+opencv+open3d实现鼠标手画多边形裁剪分割点云操作 引言使用效果:代码pcd_roi_crop.py:引言 当我们想对一个不规则物体的图像或者点云裁剪时,直接手动输入…

STM32的HAL库开发---通用定时器(TIMER)---定时器脉冲计数

一、脉冲计数实验原理 1、 外部时钟模式1&#xff1a;核心为蓝色部分的时基单元&#xff0c;时基单元的时钟源可以来自四种&#xff0c;分别是内部时钟PCLK、外部时钟模式1&#xff0c;外部时钟模式2、内部定时器触发&#xff08;级联&#xff09;。而脉冲计数就是使用外部时钟…

Redis05 - 性能调优和缓存问题

Redis性能调优和缓存问题 文章目录 Redis性能调优和缓存问题一&#xff1a;链路追踪判断是不是redis出了问题二&#xff1a;redis变慢原因1&#xff1a;使用复杂度过高的命令(*)1.1&#xff1a;查看redis慢日志1.2&#xff1a;延迟变大原因分析1.3&#xff1a;解决方案 2&#…

漫步 C++ 之途,领略引用的独特风姿

在C中&#xff0c;引用&#xff08;Reference&#xff09;是一种非常有用的特性&#xff0c;它允许为一个变量创建一个别名&#xff08;Alias&#xff09;。引用在很多情况下可以替代指针&#xff0c;但使用起来更加方便和安全。以下是对C引用的详细介绍&#xff0c;包括其定义…

Spring Boot Web 入门

目录 Spring Boot Web 是 Spring Boot 框架的一个重要模块&#xff0c;它简化了基于 Spring 的 Web 应用程序的开发过程。以下是一个 Spring Boot Web 项目的入门指南&#xff0c;涵盖了项目创建、代码编写、运行等关键步骤。 1. 项目创建 使用 Spring Initializr 使用 IDE …

Java 多线程、线程同步、线程池

一. 线程 1. 线程&#xff1a;线程(Thread)是一个程序内部的一条执行流程。 2. 程序中如果只有一条执行流程&#xff0c;那这个程序就是单线程的程序。 二. 多线程 多线程是指从硬件上实现多条执行流程的技术(多条线程由CPU负责调度) Javas是通过java.lang.Thread类的对象来代…