使用动态协议包,实现客户端与服务器端
思维导图
使用链表记录接受的值
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;
}