网络编程day2
一、套接字
二、服务器和客户端的搭建
服务器代码
#include <head.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 packsize;
//标志位,方便查找每次存储的内容
enum Type type;
//用数组存取数据
char buf[4096];
//方便在上一次读取过后连续读写
int used;
}pack_t;
int main(int argc, const char *argv[])
{
//获取终端输入的端口号,可以在终端修改端口号
if(argc<2)
{
printf("请输入端口号\n");
return 1;
}
//获取的端口号是字符串类型,用函数强转成端口号的类型
int port=atoi(argv[1]);
//创建服务器套接字文件
int server=socket(AF_INET,SOCK_STREAM,0);
//定义一个结构体变量并初始化
struct sockaddr_in addr={0};
//确定服务器ip地址和port号
addr.sin_family=AF_INET;
addr.sin_port=htons(port);
addr.sin_addr.s_addr=inet_addr("0.0.0.0");
//将服务器结构体写入套接字文件中
if(bind(server,(struct sockaddr*)&addr,sizeof(addr))==-1)
PRINT_ERROR("bind");
//监听
listen(server,50);
//连接一个客户端,获取其套接字信息
int client=accept(server,0,0);
printf("有客户连接\n");
//循环读取客户端发来的信息
while(1)
{
//定义一个协议包变量并初始化
pack_t pack={0};
int size={0};
//读取协议包大小,并获取返回值用来判断客户端是否断开
int res=read(client,&size,4);
if(res==0)
{
printf("客户端断开连接\n");
break;
}
//读取客户端数据,注意结构体pack的类型强转和偏移以及读取的数据大小
read(client,(char*)&pack+4,size-4);
printf("%ld\n",*(long*)pack.buf);
}
return 0;
}
客户端代码
#include <head.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 packsize;
enum Type type;
char buf[4096];
int used;
}pack_t;
//写一个函数:用一个数组存储字符串
void append(pack_t* pack,const char* str)
{
//定义变量
char* buf=pack->buf;
short size=strlen(str);//获取长度
*(short*)(buf+pack->used)=size;//用两个字节存储长度
pack->used+=2;//偏移size的两个字节
memcpy(buf+pack->used,str,size);//偏移后将写入的字符串存入数组buf中
pack->used+=size;//偏移
pack->packsize=pack->used+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);
//准备ip和port
struct sockaddr_in addr={0};
addr.sin_family=AF_INET;
addr.sin_port=htons(port);
addr.sin_addr.s_addr=inet_addr("192.168.127.195");
//根据准备的ip和port连接服务器
if(connect(client,(struct sockaddr*)&addr,sizeof(addr))==-1)
PRINT_ERROR("connect");
//成功连接服务器就通过客户端套接字和write或者send给服务器发送消息
while(1)
{
char name[20]="";
char pswd[20]="";
pack_t pack={0};
pack.type=Type_REGIST;
printf("请输入账户:");
scanf("%19s",name);
getchar();
printf("请输入密码:");
scanf("%19s",pswd);
getchar();
append(&pack,name);
append(&pack,pswd);
printf("%ld\n",*(long*)pack.buf);
write(client,&pack,pack.packsize);
}
return 0;
}