结构体验证

qq_29846883 2017-10-18 02:55:31
问题是这样的:
客户端有结构体
struct ts
{
int a;
char b;
short c;
};

ts t;
int len = sizeof(ts);
unsigned char * data = new unsigned char[len];
memcpy(data,&t,len);

它通过socket接口把这个结构体数据(data)传给了服务器,
那么问题是:服务器这里要怎么验证这个data数据是客户端那边定义的那个ts?
...全文
508 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
paschen 版主 2017-10-18
  • 打赏
  • 举报
回复
比如结体体加一个成员变量,存储该结构体对象MD5值,接收后验证是否正确
真相重于对错 2017-10-18
  • 打赏
  • 举报
回复
我认为安全、性能要求一般的传输,没有必要做详细的验证 如果考虑安全性的话,可以用加密传输!
  • 打赏
  • 举报
回复
xml传输也是可以的啊
  • 打赏
  • 举报
回复
引用 14 楼 qq_29846883 的回复:
我这么写的目的就是为了可以随意定义结构体,不用约束,让代码维护起来更简单,用的也简单,能找到方法就找,找不到我再换其它方法
随意定义结构也要服务器和客户端约定好啊。 或者你用json串传数据?任意结构都可以,随意定义。
qq_29846883 2017-10-18
  • 打赏
  • 举报
回复
我这么写的目的就是为了可以随意定义结构体,不用约束,让代码维护起来更简单,用的也简单,能找到方法就找,找不到我再换其它方法
  • 打赏
  • 举报
回复
引用 12 楼 qq_29846883 的回复:
才来找类似的算法啊,只校验结构体就可以, 不然我直接用crc不就好了嘛
就是约定标记,检验那个标记是否符合就好了。 这就是自定义协议啊。 如果觉得简单,那就定义复杂点。随自己怎么定义都可以。
qq_29846883 2017-10-18
  • 打赏
  • 举报
回复
引用 11 楼 zjq9931 的回复:
[quote=引用 6 楼 qq_29846883 的回复:] 这个是我的实现,校验失败了,我的目的是想收到数据后直接调用crc_check(我需要的结构体)判断是否是我要的结构体
typedef struct request
{
private:
	unsigned short crc;

public:
	unsigned int msg;
	unsigned char* data;
	unsigned int len;	

	request() {}
	~request()
	{
		if (data)
		{
			delete[]data;
		}
	}

	template<typename T> void pack(T& req)
	{
		len = sizeof(T);
		unsigned int _crclen = len / sizeof(unsigned short);
		data = new unsigned char[len];
		data[0] = 0;
		memcpy(data, &req, len);

		crc = 0;
		auto ptmp = (unsigned short*)&req;
		for (int i = 0; i < _crclen; i++)
		{
			crc += ptmp[i];
		}
	}

	template<typename T> bool crc_check(T& req)
	{
		//memcpy(data, &req, sizeof(T));
		unsigned int lengch = sizeof(T);
		auto _crclen = lengch / sizeof(unsigned short);
		unsigned short _crc = 0;
		auto ptmp = (unsigned short*)&req;
		for (int i = 0; i < _crclen; i++)
		{
			_crc += ptmp[i];
		}
		return crc == _crc;
	}
}REQ;
这个做法是检验数据是否被破坏用的,不能解决你说的问题。 你需要结构体A,我给你传了一个结构体B,这个方法不能解决这个问题。[/quote] 所以我才来找类似的算法啊,只校验结构体就可以, 不然我直接用crc不就好了嘛
  • 打赏
  • 举报
回复
引用 6 楼 qq_29846883 的回复:
这个是我的实现,校验失败了,我的目的是想收到数据后直接调用crc_check(我需要的结构体)判断是否是我要的结构体
typedef struct request
{
private:
	unsigned short crc;

public:
	unsigned int msg;
	unsigned char* data;
	unsigned int len;	

	request() {}
	~request()
	{
		if (data)
		{
			delete[]data;
		}
	}

	template<typename T> void pack(T& req)
	{
		len = sizeof(T);
		unsigned int _crclen = len / sizeof(unsigned short);
		data = new unsigned char[len];
		data[0] = 0;
		memcpy(data, &req, len);

		crc = 0;
		auto ptmp = (unsigned short*)&req;
		for (int i = 0; i < _crclen; i++)
		{
			crc += ptmp[i];
		}
	}

	template<typename T> bool crc_check(T& req)
	{
		//memcpy(data, &req, sizeof(T));
		unsigned int lengch = sizeof(T);
		auto _crclen = lengch / sizeof(unsigned short);
		unsigned short _crc = 0;
		auto ptmp = (unsigned short*)&req;
		for (int i = 0; i < _crclen; i++)
		{
			_crc += ptmp[i];
		}
		return crc == _crc;
	}
}REQ;
这个做法是检验数据是否被破坏用的,不能解决你说的问题。 你需要结构体A,我给你传了一个结构体B,这个方法不能解决这个问题。
  • 打赏
  • 举报
回复
引用 9 楼 qq_29846883 的回复:
[quote=引用 7 楼 zjq9931 的回复:] [quote=引用 6 楼 qq_29846883 的回复:] 这个是我的实现,校验失败了,我的目的是想收到数据后直接调用crc_check(我需要的结构体)判断是否是我要的结构体
typedef struct request
{
private:
	unsigned short crc;

public:
	unsigned int msg;
	unsigned char* data;
	unsigned int len;	

	request() {}
	~request()
	{
		if (data)
		{
			delete[]data;
		}
	}

	template<typename T> void pack(T& req)
	{
		len = sizeof(T);
		unsigned int _crclen = len / sizeof(unsigned short);
		data = new unsigned char[len];
		data[0] = 0;
		memcpy(data, &req, len);

		crc = 0;
		auto ptmp = (unsigned short*)&req;
		for (int i = 0; i < _crclen; i++)
		{
			crc += ptmp[i];
		}
	}

	template<typename T> bool crc_check(T& req)
	{
		//memcpy(data, &req, sizeof(T));
		unsigned int lengch = sizeof(T);
		auto _crclen = lengch / sizeof(unsigned short);
		unsigned short _crc = 0;
		auto ptmp = (unsigned short*)&req;
		for (int i = 0; i < _crclen; i++)
		{
			_crc += ptmp[i];
		}
		return crc == _crc;
	}
}REQ;
结构不变,结构里的内容变了,CRC仍然会失败,所以。。。好吧,我都不知道你想干什么了。。。[/quote] 我这个只是从CRC的基础上改, 并不是完整代码, 我想要的就是CRC它的验证模式,所以我想要类似的算法,可以直接效验结构体就行,不需要验证内容[/quote] 失败的原因是:没有跳过CRC值存储成员自身,计算时,对前两个字节不计算在内应当就可以了。
qq_29846883 2017-10-18
  • 打赏
  • 举报
回复
引用 7 楼 zjq9931 的回复:
[quote=引用 6 楼 qq_29846883 的回复:] 这个是我的实现,校验失败了,我的目的是想收到数据后直接调用crc_check(我需要的结构体)判断是否是我要的结构体
typedef struct request
{
private:
	unsigned short crc;

public:
	unsigned int msg;
	unsigned char* data;
	unsigned int len;	

	request() {}
	~request()
	{
		if (data)
		{
			delete[]data;
		}
	}

	template<typename T> void pack(T& req)
	{
		len = sizeof(T);
		unsigned int _crclen = len / sizeof(unsigned short);
		data = new unsigned char[len];
		data[0] = 0;
		memcpy(data, &req, len);

		crc = 0;
		auto ptmp = (unsigned short*)&req;
		for (int i = 0; i < _crclen; i++)
		{
			crc += ptmp[i];
		}
	}

	template<typename T> bool crc_check(T& req)
	{
		//memcpy(data, &req, sizeof(T));
		unsigned int lengch = sizeof(T);
		auto _crclen = lengch / sizeof(unsigned short);
		unsigned short _crc = 0;
		auto ptmp = (unsigned short*)&req;
		for (int i = 0; i < _crclen; i++)
		{
			_crc += ptmp[i];
		}
		return crc == _crc;
	}
}REQ;
结构不变,结构里的内容变了,CRC仍然会失败,所以。。。好吧,我都不知道你想干什么了。。。[/quote] 我这个只是从CRC的基础上改, 并不是完整代码, 我想要的就是CRC它的验证模式,所以我想要类似的算法,可以直接效验结构体就行,不需要验证内容
  • 打赏
  • 举报
回复
引用 6 楼 qq_29846883 的回复:
这个是我的实现,校验失败了,我的目的是想收到数据后直接调用crc_check(我需要的结构体)判断是否是我要的结构体
typedef struct request
{
private:
	unsigned short crc;

public:
	unsigned int msg;
	unsigned char* data;
	unsigned int len;	

	request() {}
	~request()
	{
		if (data)
		{
			delete[]data;
		}
	}

	template<typename T> void pack(T& req)
	{
		len = sizeof(T);
		unsigned int _crclen = len / sizeof(unsigned short);
		data = new unsigned char[len];
		data[0] = 0;
		memcpy(data, &req, len);

		crc = 0;
		auto ptmp = (unsigned short*)&req;
		for (int i = 0; i < _crclen; i++)
		{
			crc += ptmp[i];
		}
	}

	template<typename T> bool crc_check(T& req)
	{
		//memcpy(data, &req, sizeof(T));
		unsigned int lengch = sizeof(T);
		auto _crclen = lengch / sizeof(unsigned short);
		unsigned short _crc = 0;
		auto ptmp = (unsigned short*)&req;
		for (int i = 0; i < _crclen; i++)
		{
			_crc += ptmp[i];
		}
		return crc == _crc;
	}
}REQ;
引用 6 楼 qq_29846883 的回复:
这个是我的实现,校验失败了,我的目的是想收到数据后直接调用crc_check(我需要的结构体)判断是否是我要的结构体
typedef struct request
{
private:
	unsigned short crc;

public:
	unsigned int msg;
	unsigned char* data;
	unsigned int len;	

	request() {}
	~request()
	{
		if (data)
		{
			delete[]data;
		}
	}

	template<typename T> void pack(T& req)
	{
		len = sizeof(T);
		unsigned int _crclen = len / sizeof(unsigned short);
		data = new unsigned char[len];
		data[0] = 0;
		memcpy(data, &req, len);

		crc = 0;
		auto ptmp = (unsigned short*)&req;
		for (int i = 0; i < _crclen; i++)
		{
			crc += ptmp[i];
		}
	}

	template<typename T> bool crc_check(T& req)
	{
		//memcpy(data, &req, sizeof(T));
		unsigned int lengch = sizeof(T);
		auto _crclen = lengch / sizeof(unsigned short);
		unsigned short _crc = 0;
		auto ptmp = (unsigned short*)&req;
		for (int i = 0; i < _crclen; i++)
		{
			_crc += ptmp[i];
		}
		return crc == _crc;
	}
}REQ;
失败的原因是:没有跳过CRC值存储成员自身,计算时,对前两个字节不计算在内应当就可以了。
  • 打赏
  • 举报
回复
引用 6 楼 qq_29846883 的回复:
这个是我的实现,校验失败了,我的目的是想收到数据后直接调用crc_check(我需要的结构体)判断是否是我要的结构体
typedef struct request
{
private:
	unsigned short crc;

public:
	unsigned int msg;
	unsigned char* data;
	unsigned int len;	

	request() {}
	~request()
	{
		if (data)
		{
			delete[]data;
		}
	}

	template<typename T> void pack(T& req)
	{
		len = sizeof(T);
		unsigned int _crclen = len / sizeof(unsigned short);
		data = new unsigned char[len];
		data[0] = 0;
		memcpy(data, &req, len);

		crc = 0;
		auto ptmp = (unsigned short*)&req;
		for (int i = 0; i < _crclen; i++)
		{
			crc += ptmp[i];
		}
	}

	template<typename T> bool crc_check(T& req)
	{
		//memcpy(data, &req, sizeof(T));
		unsigned int lengch = sizeof(T);
		auto _crclen = lengch / sizeof(unsigned short);
		unsigned short _crc = 0;
		auto ptmp = (unsigned short*)&req;
		for (int i = 0; i < _crclen; i++)
		{
			_crc += ptmp[i];
		}
		return crc == _crc;
	}
}REQ;
结构不变,结构里的内容变了,CRC仍然会失败,所以。。。好吧,我都不知道你想干什么了。。。
qq_29846883 2017-10-18
  • 打赏
  • 举报
回复
这个是我的实现,校验失败了,我的目的是想收到数据后直接调用crc_check(我需要的结构体)判断是否是我要的结构体
typedef struct request
{
private:
	unsigned short crc;

public:
	unsigned int msg;
	unsigned char* data;
	unsigned int len;	

	request() {}
	~request()
	{
		if (data)
		{
			delete[]data;
		}
	}

	template<typename T> void pack(T& req)
	{
		len = sizeof(T);
		unsigned int _crclen = len / sizeof(unsigned short);
		data = new unsigned char[len];
		data[0] = 0;
		memcpy(data, &req, len);

		crc = 0;
		auto ptmp = (unsigned short*)&req;
		for (int i = 0; i < _crclen; i++)
		{
			crc += ptmp[i];
		}
	}

	template<typename T> bool crc_check(T& req)
	{
		//memcpy(data, &req, sizeof(T));
		unsigned int lengch = sizeof(T);
		auto _crclen = lengch / sizeof(unsigned short);
		unsigned short _crc = 0;
		auto ptmp = (unsigned short*)&req;
		for (int i = 0; i < _crclen; i++)
		{
			_crc += ptmp[i];
		}
		return crc == _crc;
	}
}REQ;
  • 打赏
  • 举报
回复
引用 4 楼 qq_29846883 的回复:
楼上的方法都不是很好和准确,之前都想过排除了 有没有做过CRC效验或者ip数据包校验的大佬说下怎么做?
CRC校验是传输层做的事情了。。 如果你想区分数据,而不是验证数据是否被破坏的话,肯定用不着CRC校验啊。 用windows的做法足够了,你可以把第一个成员当成ID,就可以来区分了。
qq_29846883 2017-10-18
  • 打赏
  • 举报
回复
楼上的方法都不是很好和准确,之前都想过排除了 有没有做过CRC效验或者ip数据包校验的大佬说下怎么做?
凌乱哥 2017-10-18
  • 打赏
  • 举报
回复
data前面加一些自定义的固定格式的头,两边约定好就行。服务器收到后判断头就可以知道是什么数据类型或者什么结构体了
slxixiha 2017-10-18
  • 打赏
  • 举报
回复
是否可以在结构体中增加一个变量用来标识是这个结构体
  • 打赏
  • 举报
回复
windows结构体的统一做法是:结构体的第一个成员是结构体本身的大小。 通过这样的方式来验证传过来的结构体。 这样的方法还有一个好处就是,当结构体扩展的时候,软件可以分出来是扩展前的结构体还是扩展后的结构体。

64,281

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧