Socket网络通信之发送数据包

举报
看,未来 发表于 2020/12/29 23:23:56 2020/12/29
【摘要】 目录 22.1 本篇Socket 发送数据包的具体形式 22.2 代码设计 22.3 代码 22.1 本篇Socket 发送数据包的具体格式 鉴于我被那些吹牛皮的浪费一下午的时间的惨痛经历,我就明说了,我这篇是基于结构体形式的、客户端请求服务器的、服务器接收并发送应答包的,一篇博客。 如果不是你所需要的,可以换别篇了。 22.2 代码设计 我哪个栗子吧...

目录

22.1 本篇Socket 发送数据包的具体形式

22.2 代码设计

22.3 代码


22.1 本篇Socket 发送数据包的具体格式

鉴于我被那些吹牛皮的浪费一下午的时间的惨痛经历,我就明说了,我这篇是基于结构体形式的、客户端请求服务器的、服务器接收并发送应答包的,一篇博客。
如果不是你所需要的,可以换别篇了。

22.2 代码设计

我哪个栗子吧,登录注册请求服务端应答的栗子。

当然会有更好的方法来设计

首先,需要来个表明目的的结构体,你是要干嘛,登录、注册,还是就找回密码啊或者其他的。
typedef struct pub_head
{
int fun;//发出的 0链接 1:登录 2:注册 3:找回密码 (其他再说吧,目前没想到)
}HEAD_T;

然后就需要一个请求包的结构体了,需要用户名、密码,或者还有啥其他的
typedef struct login_t
{
char username[25];
char passwd[25];
//其他再说吧
}LOGIN_M;

接下来再来一个回应包
typedef struct login_res
{
int flag; // 连接状态 1成功 0 失败
char usernaem[25];
char time[30];
}LOGIN_S; //服务器返回

嗯,一个粗略的数据包外壳包好了,该填东西了。

22.3 代码

客户端是用QT写的,前面谈过的内容就不赘述了,主要是这一块

 socket->abort(); socket->connectToHost(IP_now,PORN_now.toInt()); HEAD_T head; head.fun=1; LOGIN_M login; QByteArray name =this->NameEdit->text().toLatin1(); QByteArray pwd =this->PwdEdit->text().toLatin1(); strcpy(login.username,name.data()); strcpy(login.passwd,pwd.data()); char *data=new char[1024]; memcpy(data,&head,sizeof(HEAD_T)); memcpy(data+sizeof(HEAD_T),&login,sizeof(LOGIN_M)); socket->write(data,sizeof(HEAD_T)+sizeof(LOGIN_M));

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

服务端代码是放在Linux底下跑的C
伪代码,主要是为了突出解包及应答包

#include <stdlib.h>
#include <stdio.h>  
#include <errno.h>  
#include <string.h>  
#include <netdb.h>  
#include <sys/types.h>  
#include <netinet/in.h>  
#include <sys/socket.h> 
#include "sqlite3.h"

#define portnumber //端口号,自己设置   

int main(int argc, char *argv[])
{ //截取字符串
	HEAD_T head;
	LOGIN_M login_m;
	LOGIN_S login_s;
	char data[1024];
	int num = 0;
	int nbytes; char buffer[1024]; char *errMsg; int rc; //设置Socket属性:SO_REUSEADDR:允许在bind过程中本地地址重复使用   
	int iSockopt = 1;
	if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (const char *)&iSockopt, sizeof(int)) < 0 )
	{ close(sockfd); return -1; } while(1) { /* 服务器阻塞,直到客户程序建立连接 */ sin_size=sizeof(struct sockaddr_in); if((new_fd=accept(sockfd,(struct sockaddr *)(&client_addr),&sin_size))==-1) { fprintf(stderr,"Accept error:%s\n\a",strerror(errno)); exit(1); } fprintf(stderr,"Server get connection from %s\n",inet_ntoa(client_addr.sin_addr)); // 将网络地址转换成.字符串 if((nbytes=read(new_fd,buffer,1024))==-1) { printf("%d",nbytes); fprintf(stderr,"Read Error:%s\n",strerror(errno)); exit(1); } //下面开始解包
		buffer[nbytes]='\0'; ptr = buffer;
		memcpy(&head,ptr,sizeof(HEAD_T));
		num=head.fun; switch(num)
		{ case 0://确定连上服务器 { login_s.flag=1; printf("\ncase=%d\n",num); memcpy(data,&head,sizeof(HEAD_T)); memcpy(data+sizeof(HEAD_T),&login_s,sizeof(login_s)); write(new_fd,data,sizeof(login_s)+sizeof(head)); memset(data,0,sizeof(data)); memset(buffer,0,sizeof(buffer)); memset(&login_s,0,sizeof(login_s)); //memset(login_m,0,sizeof(login_m)); ptr=NULL; } break; case 1://登录 printf("\ncase=%d\n",num); memcpy(&login_m,ptr+sizeof(HEAD_T),sizeof(LOGIN_M)); sprintf(sql,"select * from user where name = '%s'and pwd = '%s'", login_m.username,login_m.passwd); rc = sqlite3_get_table(db,sql,&dbResult,&nRow,&nColumn,&errMsg); if(rc == SQLITE_OK && nRow == 1) { login_s.flag=1; //printf("fun=%d",head.fun); memcpy(data,&head,sizeof(HEAD_T)); memcpy(data+sizeof(HEAD_T),&login_s,sizeof(login_s)); write(new_fd,data,sizeof(login_s)+sizeof(head)); printf("\nlogin succse\n"); } else if(rc != SQLITE_OK || nRow != 1) { login_s.flag=0; memcpy(data,&head,sizeof(HEAD_T)); memcpy(data+sizeof(HEAD_T),&login_s,sizeof(login_s)); write(new_fd,data,sizeof(data)); printf("\nlocin error"); } ptr=NULL; break; case 2:// printf("case=%d\n",num); memcpy(&login_m,ptr+sizeof(HEAD_T),sizeof(LOGIN_M)); sprintf(sql,"insert into user values ('%s','%s',0,'0','0')", login_m.username,login_m.passwd); rc = sqlite3_get_table(db,sql,&dbResult,&nRow,&nColumn,&errMsg); if(rc==SQLITE_OK) printf(" \nadd success\n"); ptr=NULL; break; case 3:// printf("case=%d\n",num); memcpy(&login_m,ptr+sizeof(HEAD_T),sizeof(LOGIN_M)); printf("admin=%s,pwd=%s",login_m.username,login_m.passwd); sprintf(sql,"update user set pwd = '%s' where name = '%s'", login_m.passwd,login_m.username); rc = sqlite3_get_table(db,sql,&dbResult,&nRow,&nColumn,&errMsg); if(rc==SQLITE_OK) printf("\n updata success\n"); ptr=NULL; break; } printf("\nServer received %s\n",buffer); //这个通讯已经结束  close(new_fd); /* 循环下一个 */ } /* 结束通讯 */ close(sockfd); exit(0);  
}


  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139

当时我做雷霆战机的时候,看得我是一脸懵逼。。。
现在拿这个我能看的明白还能上注解了

文章来源: lion-wu.blog.csdn.net,作者:看,未来,版权归原作者所有,如需转载,请联系作者。

原文链接:lion-wu.blog.csdn.net/article/details/104056019

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。