socket传输结构体,或者结构体转换成字符串

BRUCE叹气 2013-05-27 04:56:13
我用SNMP的API获取了信息,现在想用socket传输到服务器端。
但结构体好像不能直接传输,但又没办转换成字符串。
求大神指点一下,该怎么办。
下面是部分代码
//查询结果
char *string = NULL;
SnmpMgrOidToStr(&variableBindings.list[0].name, &string);
printf("Variable = %s\n", string);

//发送查询结果
ret = send (sClient, (char *)&string, sizeof(string), 0);
if (string) SNMP_free(string);
if (ret == SOCKET_ERROR)
{
printf("send() failed!\n");
}
else
printf("client info has been sent!");

//转换成字符串
char str[255];
sprintf(str, "%s",&variableBindings.list[0].value);

//发送
ret = send (sClient, (char *)&str, sizeof(str), 0);
if (ret == SOCKET_ERROR)
{
printf("send() failed!\n");
}
else
printf("client info has been sent!");
printf("\n");
...全文
302 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
天朗-星空 2014-11-24
  • 打赏
  • 举报
回复
sprintf函数:字符串格式化命令,主要功能是把格式化的数据写入某个字符串中。sprintf 是个变参函数; 例如可以把
struct student{
  int num;
  char name[N];
  int age;
};
struct student st;
/*.......*/结构体初始化
char buf[N];
sprintf(buf, "%d%s%d", st.num, st.name, st.age);//会自动追加结束符
大小端问题可以用函数htonl()进行转换,不是结构体转字符串的问题,是网络字节序的问题~
BRUCE叹气 2013-05-29
  • 打赏
  • 举报
回复
仍然不能解决问题。没办法了。
AnYidan 2013-05-27
  • 打赏
  • 举报
回复
引用 6 楼 ochonglangzheo 的回复:
这个涉及到大小端问题,发送结构体的时候,如果其中一个变量超过一个字节,要进行大小端转换

//2个字节类型的转换
#define  BSWAP_16(x) \
	(UINT16) ( ((((UINT16)(x)) & 0x00ff) << 8 ) | \
			((((UINT16)(x)) & 0xff00) >> 8 ) \
		 )
//四个字节类型的转
#define BSWAP_32(x) \
	(UINT32) ( (( ((UINT32)(x)) & 0xff000000 ) >> 24) | \
			(( ((UINT32)(x)) & 0x00ff0000 ) >> 8 ) | \
			(( ((UINT32)(x)) & 0x0000ff00 ) << 8 ) | \
			(( ((UINT32)(x)) & 0x000000ff ) << 24) \
		 )


而且还要注意因为对齐而产生的填充bytes
ochonglangzheo 2013-05-27
  • 打赏
  • 举报
回复
这个涉及到大小端问题,发送结构体的时候,如果其中一个变量超过一个字节,要进行大小端转换

//2个字节类型的转换
#define  BSWAP_16(x) \
	(UINT16) ( ((((UINT16)(x)) & 0x00ff) << 8 ) | \
			((((UINT16)(x)) & 0xff00) >> 8 ) \
		 )
//四个字节类型的转
#define BSWAP_32(x) \
	(UINT32) ( (( ((UINT32)(x)) & 0xff000000 ) >> 24) | \
			(( ((UINT32)(x)) & 0x00ff0000 ) >> 8 ) | \
			(( ((UINT32)(x)) & 0x0000ff00 ) << 8 ) | \
			(( ((UINT32)(x)) & 0x000000ff ) << 24) \
		 )


starytx 2013-05-27
  • 打赏
  • 举报
回复
强制转化为BYTE数组发送,接收方再转化为结构体
BRUCE叹气 2013-05-27
  • 打赏
  • 举报
回复
引用 3 楼 spaceman10 的回复:
也可以自己打包解包封装
什么是打包解包?
spaceman10 2013-05-27
  • 打赏
  • 举报
回复
也可以自己打包解包封装
www_adintr_com 2013-05-27
  • 打赏
  • 举报
回复
你需要的是序列化, 搜索 protobuf
BRUCE叹气 2013-05-27
  • 打赏
  • 举报
回复
全部代码如下:
// d2.cpp : Defines the entry point for the DLL application.
//

#include "stdafx.h"
#include "d2.h"

#include <stdlib.h>
#include <winsock2.h>
#define SERVER_PORT 5208 //ÕìÌý¶Ë¿Ú


#include <windows.h>
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <snmp.h>
#include <mgmtapi.h>
#pragma comment(lib,"Mgmtapi.lib")
#pragma comment(lib,"Snmpapi.lib")

#define GET     1
#define GETNEXT 2
#define WALK    3
#define TRAP    4
#define TIMEOUT 6000 /* milliseconds */
#define RETRIES 3

extern "C" __declspec(dllexport) int main()
{

     char a[100];    //=".1.3.6.1.2.1.1"
	 char b[100];    //´æ·ÅIPµØÖ·
	 char *SnmpOid;
	 int                operation;
	 RFC1157VarBindList variableBindings;
	 LPSNMP_MGR_SESSION session;
	 
	 int        timeout = TIMEOUT;
	 int        retries = RETRIES;
	
	 BYTE       requestType;
	 AsnInteger errorStatus;
	 AsnInteger errorIndex;
 	 char        *chkPtr = NULL;//»¹Ã»¸ãÃ÷°×ÕâÊǸÉÂïµÄ
	 operation = WALK;
	 
	 //socket µÄ¶¨Òå
	 WORD wVersionRequested;
	 WSADATA wsaData;
	 int ret;
	 SOCKET sClient; //Á¬½ÓÌ×½Ó×Ö
	 struct sockaddr_in saServer; //µØÖ·ÐÅÏ¢
	
	 BOOL fSuccess = TRUE;
	
	 //WinSock³õʼ»¯
	 wVersionRequested = MAKEWORD(2, 2); //Ï£ÍûʹÓõÄWinSock DLLµÄ°æ±¾
	 ret = WSAStartup(wVersionRequested, &wsaData);
	 if(ret!=0)
	 {
		 printf("WSAStartup() failed!\n");
		 return 1;
	 }
	 
	 //È·ÈÏWinSock DLLÖ§³Ö°æ±¾2.2
	 if(LOBYTE(wsaData.wVersion)!=2 || HIBYTE(wsaData.wVersion)!=2)
	 {
		 WSACleanup();
		 printf("Invalid WinSock version!\n");
		 return 1;
	 }

	 //´´½¨Socket,ʹÓÃTCPЭÒé
	 sClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	 if (sClient == INVALID_SOCKET)
	 {
		 WSACleanup();
		 printf("socket() failed!\n");
		 return 1;
	 }
 

     printf("input the ip address:");
	 scanf("%s",&b);//ÊäÈëIPµØÖ·
	 printf("input the oid:");
	 scanf("%s",&a);
	 printf("%s",a);
	 SnmpOid=&*a;	

	//¹¹½¨·þÎñÆ÷µØÖ·ÐÅÏ¢
	saServer.sin_family = AF_INET; //µØÖ·¼Ò×å
	saServer.sin_port = htons(SERVER_PORT); //×¢Òâת»¯ÎªÍøÂç½ÚÐò
	saServer.sin_addr.S_un.S_addr = inet_addr(b);//·þÎñÆ÷µØÖ·

	//Á¬½Ó·þÎñÆ÷
	ret = connect(sClient, (struct sockaddr *)&saServer, sizeof(saServer));
	if (ret == SOCKET_ERROR)
	{
        printf("connect() failed!\n");
        closesocket(sClient); //¹Ø±ÕÌ×½Ó×Ö
        WSACleanup();
        return 1;
	}


	{
		AsnObjectIdentifier reqObject;
		variableBindings.list = NULL;
	  variableBindings.len = 0;

    
	//°Ñ×Ö·û´®×ª»»³É±ê×¼OID
	if (!SnmpMgrStrToOid(SnmpOid, &reqObject))
		{
		printf("Error: Invalid oid.\n");
		return 1;
		}
	else
		{
			printf("oid is ok.\n");
				variableBindings.len++;
			if ((variableBindings.list = (RFC1157VarBind *)SNMP_realloc(
					variableBindings.list, sizeof(RFC1157VarBind) *
					variableBindings.len)) == NULL)
			{
			printf("Error: Error allocating oid.\n");
			return 1;
			}
			printf("allocate oid is ok.\n");
			variableBindings.list[variableBindings.len - 1].name=reqObject; 
			 variableBindings.list[variableBindings.len - 1].value.asnType=ASN_NULL;
		}

	if (operation == WALK && variableBindings.len != 1)
		{
		printf("Error: Multiple oids specified for WALK.\n");
		return 1;
        }
	
	if ((session = SnmpMgrOpen("127.0.0.1", "public", timeout, retries)) == NULL)
		{
		printf("error on SnmpMgrOpen.\n");
		return 1;
		}
	else printf("session is ok.\n");
	}

	{
		
        AsnObjectIdentifier root;
        AsnObjectIdentifier tempOid;
        SnmpUtilOidCpy(&root, &variableBindings.list[0].name);
        requestType = ASN_RFC1157_GETNEXTREQUEST;
		
		printf("start snmpmgr.\n");
        while(1)
		{
            if (!SnmpMgrRequest(session, requestType, &variableBindings,
				&errorStatus, &errorIndex))
			{
                printf("error on SnmpMgrRequest %d.\n Error: errorStatus=%d, errorIndex=%d \n",GetLastError(),errorStatus, errorIndex);
                break;
			}
            else
			{
                printf("request is ok.\n");

				if (errorStatus == SNMP_ERRORSTATUS_NOSUCHNAME ||
					SnmpUtilOidNCmp(&variableBindings.list[0].name,
					&root, root.idLength))
					{
						printf("End of MIB subtree.\n\n");
						break;
					}
				
				if (errorStatus > 0)
					{
						printf("Error: errorStatus=%d, errorIndex=%d \n", errorStatus, errorIndex);
						break;
					}
				else
					{
						// ·¢²éѯ½á¹û
						char *string = NULL;
						SnmpMgrOidToStr(&variableBindings.list[0].name, &string);
						printf("Variable = %s\n", string);
					                         
						//·¢ËÍ
						ret = send (sClient, (char *)&string, sizeof(string), 0);
						if (string) SNMP_free(string);
						if (ret == SOCKET_ERROR)
						{
							printf("send() failed!\n");
						}
						else
							printf("client info has been sent!");

						//ת»»³É×Ö·û´®
						char str[255];
						sprintf(str, "%s",&variableBindings.list[0].value);

						
						//·¢ËÍ
						ret = send (sClient, (char *)&str, sizeof(str), 0);
						if (ret == SOCKET_ERROR)
						{
							printf("send() failed!\n");
						}
						else
							printf("client info has been sent!");
											
						printf("\n");
					}
			
			} // end if()
			// ×¼±¸ÏÂÒ»´Î²éѯ
			SnmpUtilOidCpy(&tempOid, &variableBindings.list[0].name);
			SnmpUtilVarBindFree(&variableBindings.list[0]);
			SnmpUtilOidCpy(&variableBindings.list[0].name, &tempOid);
			variableBindings.list[0].value.asnType = ASN_NULL;
			SnmpUtilOidFree(&tempOid);
		} // end while()
		// ÊÍ·Å×ÊÔ´
		
		SnmpUtilVarBindListFree(&variableBindings);
		SnmpUtilOidFree(&root);
	}
	closesocket(sClient); //¹Ø±ÕÌ×½Ó×Ö
	WSACleanup();
	
	// ¹Ø±Õ SNMP session 
	if (!SnmpMgrClose(session))
    {
		printf("error on SnmpMgrClose %d\n");
		return 1;
    }
	
	
	return 0;
 }

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
					 )
{
    switch (ul_reason_for_call)
	{
		case DLL_PROCESS_ATTACH:
		case DLL_THREAD_ATTACH:
		case DLL_THREAD_DETACH:
		case DLL_PROCESS_DETACH:
			break;
    }
    return TRUE;
}


// This is an example of an exported variable
D2_API int nD2=0;

// This is an example of an exported function.
D2_API int fnD2(void)
{
	return 42;
}

// This is the constructor of a class that has been exported.
// see d2.h for the class definition
CD2::CD2()
{ 
	return; 
}

结合视频效果更好 https://www.bilibili.com/video/av81167448?p=189 1. 初识Go语言 1 1.1 Go语言介绍 1 1.1.1 Go语言是什么 1 1.1.2 Go语言优势 1 1.1.3 Go适合用来做什么 2 1.2 环境搭建 2 1.2.1 安装和设置 2 1.2.2 标准命令概述 2 1.2.3 学习资料 3 1.3 第一个Go程序 3 1.3.1 Hello Go 3 1.3.2 代码分析 3 1.3.3 命令行运行程序 4 2. 基础类型 4 2.1 命名 4 2.2 变量 5 2.2.1 变量声明 5 2.2.2 变量初始化 6 2.2.3 变量赋值 6 2.2.4 匿名变量 6 2.3 常量 7 2.3.1 字面常量(常量值) 7 2.3.2 常量定义 8 2.3.3 iota枚举 8 2.4 基础数据类型 10 2.4.1 分类 10 2.4.2 布尔类型 11 2.4.3 整型 11 2.4.4 浮点型 11 2.4.5 字符类型 11 2.4.6 字符串 12 2.4.7 复数类型 12 2.5 fmt包的格式化输出输入 13 2.5.1 格式说明 13 2.5.2 输出 14 2.5.3 输人 14 2.6 类型转换 15 2.7 类型别名 15 3. 运算符 15 3.1 算术运算符 15 3.2 关系运算符 16 3.3 逻辑运算符 16 3.4 位运算符 16 3.5 赋值运算符 17 3.6 其他运算符 17 3.7 运算符优先级 17 4. 流程控制 18 4.1 选择结构 18 4.1.1 if语句 18 4.1.2 switch语句 19 4.2 循环语句 20 4.2.1 for 20 4.2.2 range 20 4.3 跳转语句 21 4.3.1 break和continue 21 4.3.2 goto 21 5. 函数 22 5.1 定义格式 22 5.2 自定义函数 22 5.2.1 无参无返回值 22 5.2.2 有参无返回值 23 5.2.3 无参有返回值 24 5.2.4 有参有返回值 25 5.3 递归函数 26 5.4 函数类型 27 5.5 匿名函数与闭包 27 5.6 延迟调用defer 30 5.6.1 defer作用 30 5.6.2 多个defer执行顺序 30 5.6.3 defer和匿名函数结合使用 31 5.7 获取命令行参数 31 5.8 作用域 32 5.8.1 局部变量 32 5.8.2 全局变量 33 5.8.3 不同作用域同名变量 33 6. 工程管理 34 6.1 工作区 34 6.1.1 工作区介绍 34 6.1.2 GOPATH设置 35 6.2 包 35 6.2.1 自定义包 35 6.2.2 main包 36 6.2.3 main函数和init函数 36 6.2.4 导入包 38 6.3 测试案例 40 6.3.1 测试代码 40 6.3.2 GOPATH设置 42 6.3.3 编译运行程序 43 6.3.4 go install的使用 43 7. 复合类型 45 7.1 分类 45 7.2 指针 45 7.2.1 基本操作 45 7.2.2 new函数 46 7.2.3 指针做函数参数 46 7.3 数组 47 7.3.1 概述 47 7.3.2 操作数组 47 7.3.3 在函数间传递数组 48 7.4 slice 49 7.4.1 概述 49 7.4.2 切片的创建和初始化 49 7.4.3 切片的操作 50 7.4.4 切片做函数参数 52 7.5 map 53 7.5.1 概述 53 7.5.2 创建和初始化 53 7.5.3 常用操作 54 7.5.4 map做函数参数 55 7.6 结构体 56 7.6.1 结构体类型 56 7.6.2 结构体初始化 57 7.6.3 结构体成员的使用 57 7.6.4 结构体比较 58 7.6.5 结构体作为函数参数 59 7.6.6 可见性 59 8. 面向对象编程 61 8.1 概述 61 8.2 匿名组合 61 8.2.1 匿名字段 61 8.2.2 初始化 62 8.2.3 成员的操作 62 8.2.4 同名字段 63 8.2.5 其它匿名字段 64 8.3 方法 65 8.3.1 概述 65 8.3.2 为类型添加方法 66 8.3.3 值语义和引用语义 67 8.3.4

69,369

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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