欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 艺术 > 网络编程day2-套接字与TPC服务器与客户端的搭建

网络编程day2-套接字与TPC服务器与客户端的搭建

2025/2/8 13:55:46 来源:https://blog.csdn.net/Ryan_Gosling/article/details/145502745  浏览:    关键词:网络编程day2-套接字与TPC服务器与客户端的搭建

1.思维导图

2. TPC服务器与客户端的搭建

要点:动态协议包防止粘包

服务器

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.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 Pack
{int size;enum Type type;char buf[2048];int count;
}pack_t;void read_pack(pack_t* pack)
{char* buf=pack->buf;int readed_size = 0;while(1){short data_size = *(short*)(buf+readed_size);if(data_size==0){//	printf("数据解析完毕\n");break;}readed_size+=2;char temp[data_size+1];memset(temp,0,data_size+1);memcpy(temp,buf+readed_size,data_size);readed_size+=data_size;printf("temp=%s\n",temp);}}int main(int argc, const char *argv[])
{if(argc!=2){printf("请输入端口号\n");return 1;}// ./server 7777int port=atoi(argv[1]);//将字符串 7777 转换为int 类型port//创建服务器套接字int server = socket(AF_INET,SOCK_STREAM,0);//准备网络地址结构体:struct sockaddr_inaddr_in_t addr={0};addr.sin_family = AF_INET;//固定addr.sin_port=htons(port);//port转换为网络字节序addr.sin_addr.s_addr = inet_addr("0.0.0.0");//ip转换为unsigned int//为服务器套接字绑定ip和portif(bind(server,(addr_t*)&addr,sizeof(addr))==-1)//需要强转{perror("bind");return 1;}//监听listen(server,10);//接受客户端的连接addr_in_t cilent_addr={0};int cilent_addr_len =sizeof(cilent_addr);int cilent = accept(server,(addr_t*)&cilent_addr,&cilent_addr_len);//需要强转if(cilent!=-1){printf("有客户端连接\n");}//读取客户端发来的消息while(1){int pack_size=0;read(cilent,&pack_size,4);//先读取sizepack_t pack={0};int res=read(cilent,(char*)&pack+4,pack_size-4);//读取size后的内容if(res==0){printf("客户端断开连接\n");break;}pack.size=pack_size;//给新创建的size赋值read_pack(&pack);}return 0;
}

客户端

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.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 Pack//协议包
{int size; //用来记录整个协议包的实际大小,占四个字节  定长部分enum Type type;//占4个字节  变长部分char buf[2048];//占count个字节  不传输部分int count;//用来记录指针的偏移量,也就是buf使用了多少字节
}pack_t;void append(pack_t* pack,const char* data)
{char* buf=pack->buf;int len=strlen(data);*(short*)(buf+pack->count)=len;//将buf的前两个字节当做short来存储数据lenpack->count+=2;//偏移两个字节memcpy(buf+pack->count,data,len);//把数据内容拷贝到buf中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 cilent=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.217.128");if(connect(cilent,(addr_t*)&addr,sizeof(addr))==-1)//连接服务器{perror("connect");return 1;}while(1){pack_t pack={0};char name[20]="";char pswd[20]="";pack.type=TYPE_REGIST;printf("请输入账号:");scanf("%20s",name);while(getchar()!=10);printf("请输入密码:");scanf("%20s",pswd);while(getchar()!=10);append(&pack,name);append(&pack,pswd);write(cilent,&pack,pack.size);//type占了四个字节}return 0;
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com