通过SOCKET发送、接收结构体数据
1、
记录一下如何使用SOCKET发送、接收结构体数据。
现有如下结构体:
typedef STRUCT USERINFO
{
char name[30];
char addr[100];
int age;
};
定义结构体对象:
USERINFO usreInfo;
//发送结构体数据
send(sock, (char *)&userInfo, sizeof(USERINFO)+1, 0);
//接收结构体数据
char recvMsg[1024];
USERINFO usserInfo;
int rs = recv(sock, recvMsg, 1024, 0);
memcpy(&usserInfo, recvMsg,sizeof(USERINFO)+1);
PS: 之所以会有+1的操作,是因为在SOCKET协议中,数据的传输只能是以字符串的格式传输,而正确的字符串都是已 \0 结尾的,+1的操作即是在原有的字符串之上又重新添加了一个字节的长度用来存储字符串结尾符号。
该方法之所已成功的一个前提 是与数据在内存中存储的方式有关,对于一组数据来说,不管是整型、字符型、还是结构体类型,在内存中都是以一整块连续的内存地址存储的。
2、
需要说明的是,上面所提到的方法在vc++6.0以及vs2010下亲测可用,并且也应用到了实际的项目中,没有出现问题。但是今天在用vs2012下用时,发现会报 “变量*周围的栈损坏”的异常,经检查,发现可能是和接收时的写法有关系,因为在上面的写法中memcpy(&usserInfo, recvMsg,sizeof(USERINFO)+1); memcpy实际上是拷贝了sizeof(USERINFO)+1各字节到usserInfo所在的地址空间中,但是实际上usserInfo只占用了sizeof(USERINFO)各字节,亦即造成了内存地址越界行为,引起了错误;
为了解决这种错误,特采取了以下的写法:
typedef STRUCT USERINFO
{
char info[1024];
};
定义结构体对象:
USERINFO usreInfo;
memset(&userInfo, 0, sizeof(USERINFO));//执行初始化工作
/*
结构体赋值操作
*/
//发送结构体数据
send(sock, (char *)&userInfo, sizeof(USERINFO), 0);
//接收结构体数据
char recvMsg[1024];
USERINFO usserInfo;
memset(&userInfo, 0, sizeof(USERINFO));//执行初始化工作
int rs = recv(sock, recvMsg, 1024, 0);
memcpy(&usserInfo, recvMsg,sizeof(USERINFO));
上面那种新的写法,亲测在vs2012下可用。