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");
...全文
339 9 打赏 收藏 转发到动态 举报
AI 作业
写回复
用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; 
}

70,023

社区成员

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

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