当前位置: 首页 > article >正文

使用动态协议包,实现客户端与服务器端

思维导图

使用链表记录接受的值

resver.c(服务器)

#include <stdio.h>
#include <string.h>
#include <unistd.h> 
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>
#include <semaphore.h>
#include <wait.h>
#include <signal.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <semaphore.h>
#include <sys/msg.h>
#include <sys/shm.h>
#include <sys/un.h>

typedef struct sockaddr_in addr_in_t;
typedef struct sockaddr addr_t;
typedef struct sockaddr_un addr_un_t;


enum Type{
	type_regist,
	type_login,
};
typedef struct{
	int size;
	enum Type type;
	char buf[1024];
	int count;
}pack_t;

typedef struct Node{
	union{
		char arr[20];
		int len;
	};
	struct Node* next;
}node,*nodeptr;

nodeptr create()
{
	nodeptr h=(nodeptr)malloc(sizeof(node));
	if(NULL==h)
	{
		printf("创建失败\n");
		return NULL;
	}
	h->len=0;
	h->next=NULL;

	return h;
}
int empt(nodeptr h)
{
	if(NULL==h)
	{
		printf("判空失败\n");
		return -1;
	}
	return h->len==0;
}
void  add(nodeptr h,char* data)
{
	if(NULL==h)
	{
		printf("链表不存在\n");
		return;
	}
	nodeptr p=(nodeptr)malloc(sizeof(node));
	if(NULL==p)
	{
		printf("增加失败\n");
	}
	strcpy(p->arr,data);
	nodeptr h1=h;//尾插
	while(h1->next!=NULL)
	{
		h1=h1->next;
	}
	h1->next=p;
	p->next=NULL;
	return ;
}

void show(nodeptr h)
{
	if(NULL==h || empt(h))
	{
		printf("展示失败\n");
		return ;
	}
	nodeptr p=h->next;
	while(p!=NULL)
	{
		printf("%s\n",p->arr);
		p=p->next;
	}
	return ;
}

void read_pack(pack_t* pack,nodeptr h)
{
	char *arf=pack->buf;
	int read_size=0;
	while(1)
	{
		short len=*(short *)(arf+read_size);
		if(len==0){
			printf("解析完毕\n");
			break;
		}
		read_size+=2;
		char data[len];
		memset(data,0,len);
		memcpy(data,arf+read_size,len);
		read_size+=len;
		printf("数据:%s\n",data);
		add(h,data);
		sleep(1);
	}
}
int main(int argc, const char *argv[])
{
	if(argc!=2)
	{
		printf("请输入端口号\n");
		return 1;
	}
	int port=atoi(argv[1]);
	//服务器套接字
	int resver=socket(AF_INET,SOCK_STREAM,0);
	//网络地址结构体准备
	addr_in_t addr={0};
	addr.sin_family=AF_INET;
	addr.sin_port=htons(port);
	addr.sin_addr.s_addr=inet_addr("0.0.0.0");
	//绑定ip与port
	int res=bind(resver,(addr_t*)&addr,sizeof(addr));
	if(res==-1){
		perror("bind");
		return 1;
	}
	//监听
	listen(resver,10);
	//接收客户端链接
	addr_in_t client_addr={0};
	int client_addr_len=sizeof(client_addr);
	int client=accept(resver,(addr_t*)&client_addr,&client_addr_len);
	//读取客户端消息
	nodeptr h=create();
	while(1)
	{
		pack_t pack={0};
		int read_size=0;
		read(client,&read_size,4);
		pack.size=read_size;
		int a=read(client,(char *)&pack+4,read_size-4);
		if(a==0)
		{
			printf("客户端断开连接\n");
			break;
		}
		read_pack(&pack,h);
	}
	show(h);
	return 0;
}

client.c(客户端)

#include <stdio.h>
#include <string.h>
#include <unistd.h> 
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>
#include <semaphore.h>
#include <wait.h>
#include <signal.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <semaphore.h>
#include <sys/msg.h>
#include <sys/shm.h>
#include <sys/un.h>

typedef struct sockaddr_in addr_in_t;
typedef struct sockaddr addr_t;
typedef struct sockaddr_un addr_un_t;
enum Type{
	type_regist,
	type_login,
};
typedef struct{
	int size;
	enum Type type;
	char buf[1024];
	int count;
}pack_t;

void addend(pack_t* pack,char* date)
{
	int len=strlen(date);
	char* arf=pack->buf;
	*(short*)(arf+pack->count)=len;
	pack->count+=2;
	memcpy(arf+pack->count,date,len);
	pack->count+=len;
	pack->size=pack->count+8;
}


int main(int argc, const char *argv[])
{
	if(argc!=2)
	{
		printf("请输入端口号\n");
		return 1;
	}
	int port=atoi(argv[1]);
	//客户端套接字
	int client=socket(AF_INET,SOCK_STREAM,0);
	//客户端结构体准备
	addr_in_t addr={0};
	addr.sin_family=AF_INET;
	addr.sin_port=htons(port);
	addr.sin_addr.s_addr=inet_addr("192.168.127.63");
	//使用connect函数绑定
	int res=connect(client,(addr_t*)&addr,sizeof(addr));
	if(res==-1)
	{
		perror("connect");
		return 1;
	}
	while(1)
	{
		pack_t pack={0};
		char name[20]="0";
		char pwd[20]="0";

		printf("请输入用户名:");
		scanf("%s",name);
		while(getchar()!=10);
		printf("请输入密码:");
		scanf("%s",pwd);
		while(getchar()!=10);

		addend(&pack,name);
		addend(&pack,pwd);

		write(client,&pack,pack.size);
	}
	//输出数据
	return 0;
}

 


http://www.kler.cn/a/536589.html

相关文章:

  • 解决 ssh: connect to host github.com port 22: Connection timed out
  • c++计算机教程
  • 4.PPT:日月潭景点介绍【18】
  • 杭州某小厂面试
  • 探索 GraphQL:API 设计的未来趋势
  • Spring 核心技术解析【纯干货版】-Spring 数据访问模块 Spring-Jdbc
  • 【探商宝】DeepSeek 最新模型对 ChatGPT 的影响及行业新变革
  • Java全栈项目:酒店客房管理系统
  • 【华为OD机考】2024E+D卷真题【完全原创题解 详细考点分类 不断更新题目 六种主流语言Py+Java+Cpp+C+Js+Go】
  • Java基础知识总结(四十八)--TCP传输、TCP客户端、TCP服务端
  • OnlyOffice 全面指南:从基础使用到深度自定义
  • postgreSQL16.6源码安装
  • unity学习29:摄像机camera相关skybox 和 Render Texture测试效果
  • IDEA启动项目慢问题处理
  • 详解代理模式
  • VSCode便捷开发
  • JS逆向案例-ali231补环境 - 14
  • 日本游戏机市场5年来首次陷入萎缩;特斯拉招人推进人形机器人量产;任天堂专利显示Switch2手柄可用作鼠标...| 游戏智眼日报
  • AWS SMS短信通知实战:使用 Pinpoint SMS Voice V2 完整指南
  • MFC 应用最小化到系统托盘
  • NetCore Consul动态伸缩+Ocelot 网关 缓存 自定义缓存 + 限流、熔断、超时 等服务治理
  • 如何轻松将Matlab生成的图表嵌入PowerPoint演示文稿
  • 23、深入理解 Java Stream:高效处理数据的利器
  • 什么是高光谱成像相机?
  • .NET周刊【1月第3期 2025-01-19】
  • 网站改HTTPS方法