网络编程 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; //ipv4int 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; //读写位置 初始化为0int 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;//读取字符串数据 写入到bufDataType 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; //ipv4int 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;
}
效果