• sock通信--数据结构的传送


    新版下载频道上线初期常见问题解答!!                bShare分享,迅速提升10倍流量

    sock通信--数据结构的传送

    分类: Linux程序设计(C/C++) 164人阅读 评论(2) 收藏 举报

      sock通信中有几个问题必须注意,由于标准的不统一,有的机器使用的大端存储,而有的机器使用的是小端存储(如果对大小端不了解可以上网搜寻一下相关信息). 我们的机器的存储方式各不相同,但是由于历史原因,网络字节序使用的是大端,也就是说,我们要通过网络传输信息到远断,我们要当心了.

      如果明确了传送信息的双方都是相同的存储方式那么还好办,如果传送双方的存储方式不相同或者不一定相同,我们就必须把发送的数据进行相应的格式转换再发送到网络上,直至远端.

      由于网络字节序是大端,那么,我们再发送一个数据结构时,需要把这个结构中的每个成员转换成网络字节序,再发送到远端,而不只是简单的发送这些数据给远端.

      下面是我在发送数据结构时使用的一些例程,希望对涉及到这方面的朋友有帮助.

      在这个例子中,我定义了一个这样的结构体进行传送


    typedef struct
    {
        uint16_t packetlen;
        uint8_t cmdtype;
        uint16_t sessionid;
        uint16_t messageid;
        uint32_t ackinfo;
    } ControlHeader;


      定义了这些函数处理结构体中的成员,把他们转换成相应的格式存入缓存中
    //
    //basic convert funtion declaration
    //
    void SendUint32_tToBuff(char *buf, uint32_t n);
    void SendUint16_tToBuff(char *buf, uint16_t n);
    void SendStringToBuff(char *buf, char *str);
    uint32_t GetUint32_tFromBuff(char *buf);
    uint16_t GetUint16_tFromBuff(char *buf);

    //
    //structure convert function declaration
    //
    void init_ControlHeader(uint8_t type, uint16_t sid, uint16_t mid,
    uint32_t ack, ControlHeader *pHead);
    void sendHeadtobuff(char *buf, ControlHeader *pHead);
    void getHeaderfrombuff(void *buff, ControlHeader *p);
    int getHeadlen();

      上述定义存放在struct.h文件中,另外写了一个struct.c对上述声明进行定义

    1. #include "struct.h"   
    2. #include <stdio.h>   
    3. #include <strings.h>   
    4.   
    5. //#define TEST 1    
    6. //   
    7. //basic convert funciton definition   
    8. //   
    9. void SendUint32_tToBuff(char *buf, uint32_t n)  
    10. {  
    11.     n = htonl(n);  
    12.     bcopy((char *)&n, buf, sizeof(uint32_t));  
    13. }  
    14. void SendUint16_tToBuff(char *buf, uint16_t n)  
    15. {  
    16.     n = htons(n);  
    17.     bcopy((char *)&n, buf, sizeof(uint16_t));  
    18. }  
    19. uint32_t GetUint32_tFromBuff(char *buf)  
    20. {  
    21.     uint32_t n;  
    22.     bcopy(buf, (void *)&n, sizeof(uint32_t));  
    23.     n = ntohl(n);  
    24.     return n;  
    25. }  
    26. uint16_t GetUint16_tFromBuff(char *buf)  
    27. {  
    28.     uint16_t n;  
    29.     bcopy(buf, (void *)&n, sizeof(uint16_t));  
    30.     n = ntohs(n);  
    31.     return n;  
    32. }  
    33. //   
    34. //structure convert function declaration   
    35. //   
    36. void init_ControlHeader(uint8_t type, uint16_t sid, uint16_t mid,  
    37. uint32_t ack, ControlHeader *pHead)  
    38. {  
    39.     pHead->cmdtype = type;  
    40.     pHead->sessionid = sid;  
    41.     pHead->messageid = mid;  
    42.     pHead->ackinfo = ack;  
    43. }  
    44. int getHeadlen()  
    45. {  
    46.     return (sizeof(uint16_t)+sizeof(uint8_t)+sizeof(uint16_t)  
    47. +sizeof(uint16_t)+sizeof(uint32_t));  
    48. }  
    49. void sendHeadtobuff(char *buf, ControlHeader *pHead)  
    50. {  
    51.     char *pos = buf;  
    52.       
    53.     if(buf == NULL)  
    54.         fprintf(stderr, "encouter NULL pointer in sendheadertobuff/n");  
    55.     else  
    56.     {  
    57.         SendUint16_tToBuff(pos, pHead->packetlen);  
    58.         pos += sizeof(uint16_t);  
    59.         *pos = pHead->cmdtype;  
    60.         pos++;  
    61.         SendUint16_tToBuff(pos, pHead->sessionid);  
    62.         pos += sizeof(uint16_t);  
    63.         SendUint16_tToBuff(pos, pHead->messageid);  
    64.         pos += sizeof(uint16_t);  
    65.         SendUint32_tToBuff(pos, pHead->ackinfo);          
    66.     }  
    67. }  
    68. void getHeaderfrombuff(void *pbuff, ControlHeader *p)  
    69. {  
    70.     char *buf = (void *)pbuff;  
    71.     bcopy(buf, (void *)&p->packetlen, sizeof(uint16_t));  
    72.     p->packetlen = ntohs(p->packetlen);  
    73.     buf += sizeof(uint16_t);  
    74.       
    75.     p->cmdtype = *buf;  
    76.     buf += 1;  
    77.       
    78.     bcopy(buf, (void *)&p->sessionid, sizeof(uint16_t));  
    79.     p->sessionid = ntohs(p->sessionid);  
    80.     buf += sizeof(uint16_t);  
    81.       
    82.     bcopy(buf, (void *)&p->messageid, sizeof(uint16_t));  
    83.     p->messageid = ntohs(p->messageid);  
    84.     buf += sizeof(uint16_t);  
    85.       
    86.     bcopy(buf, (void *)&p->ackinfo, sizeof(uint32_t));  
    87.     p->ackinfo = ntohl(p->ackinfo);  
    88. }  
    89. #ifdef TEST   
    90. int main(int argc, char **argv)  
    91. {  
    92.     ControlHeader myheader;  
    93.     ControlHeader myh;  
    94.     uint8_t type = 1;  
    95.     uint16_t len = 2, sid = 3, mid = 4;  
    96.     uint32_t ackif = 5;  
    97.     char buf[128];  
    98.     int length = getHeadlen();  
    99.       
    100.     init_ControlHeader(type, sid, mid, ackif, &myheader);  
    101.     //see whether init_ControlHeader function right   
    102.     printf("myheader.cmdtype = %d/n", myheader.cmdtype);  
    103.       
    104.     SendUint32_tToBuff(buf, ackif);  
    105.     //see whether SendUint32_tToBuff function right   
    106.     printf("getuint32_tfrombuff : %d/n", GetUint32_tFromBuff(buf));  
    107.     SendUint16_tToBuff(buf, len);  
    108.     //see whether SendUint32_tToBuff function right   
    109.     printf("getuint16_tfrombuff : %d/n", GetUint16_tFromBuff(buf));  
    110.       
    111.     printf("header length is %d/n", length);  
    112.     sendHeadtobuff(buf, &myheader);  
    113.     //buf[length] = 0;   
    114.     printf("buf is %s/n", buf);  
    115.       
    116.     getHeaderfrombuff(buf, &myh);  
    117.     printf("myh.cmdtype = %d/n", myh.cmdtype);   
    118. }  
    119. #endif  
     

      下面我们写一个简单的网络通信例程,进行试验

      服务器端

    1. #include "unp.h"   
    2. #include <signal.h>   
    3. #include "struct.h"   
    4. #define SRV_PORT 5000   
    5. ControlHeader ch;  
    6. void sig_child(int signo)  
    7. {  
    8.     pid_t pid;  
    9.     int stat;  
    10.       
    11.     pid=wait(&stat);  
    12.     printf("child %d terminated/n",pid);  
    13.     return ;  
    14. }  
    15. void str_echo(int sockfd)  
    16. {  
    17.     char buf[1024];  
    18.     ssize_t n;  
    19.     n=Read(sockfd,buf,MAXLINE);  
    20.     if(n == 0)  
    21.         return ;  
    22.     //printf("bus is : %s/n", buf);   
    23.       
    24.     getHeaderfrombuff(buf, &ch);  
    25.     printf("ch.cmdtype = %d/n", ch.cmdtype);  
    26. }  
    27. int main(int argc,char **argv)  
    28. {  
    29.     int listenfd,connfd;  
    30.     pid_t childpit;  
    31.     socklen_t socklen;  
    32.     struct sockaddr_in cli_addr,srv_addr;  
    33.       
    34.     listenfd=Socket(AF_INET,SOCK_STREAM,0);  
    35.       
    36.     bzero(&srv_addr,sizeof(srv_addr));  
    37.     srv_addr.sin_family=AF_INET;  
    38.     srv_addr.sin_port=htons(SRV_PORT);  
    39.     srv_addr.sin_addr.s_addr=htonl(INADDR_ANY);  
    40.       
    41.     Bind(listenfd,(struct sockaddr *)&srv_addr,sizeof(srv_addr));  
    42.       
    43.     Listen(listenfd,LISTENQ);  
    44.     if(signal(SIGCHLD,sig_child)==SIG_ERR)  
    45.     err_sys("signal");  
    46.     /* 
    47.     for(;;) 
    48.     { 
    49.     socklen=sizeof(cli_addr); 
    50.     connfd=Accept(listenfd,(struct sockaddr *)&cli_addr,&socklen); 
    51.     if((childpit=fork())==0) 
    52.     { 
    53.         Close(listenfd); 
    54.         str_echo(connfd); 
    55.         exit(0); 
    56.         } 
    57.     Close(connfd); 
    58.     }*/  
    59.     socklen=sizeof(cli_addr);  
    60.     connfd=Accept(listenfd,(struct sockaddr *)&cli_addr,&socklen);  
    61.     str_echo(connfd);  
    62.       
    63.     exit(0);  
    64. }  

    客户端

    1. #include "unp.h"   
    2. #include "struct.h"   
    3. #define SRV_PORT 5000   
    4. ControlHeader ch;  
    5. void str_cli(int sockfd)  
    6. {  
    7.     ControlHeader ano;  
    8.     ssize_t n;  
    9.     uint8_t type = 1;  
    10.     uint16_t sid = 2;  
    11.     uint16_t mid = 3;  
    12.     uint32_t ack = 4;  
    13.     init_ControlHeader(type, sid, mid, ack, &ch);  
    14.     printf("ch.type = %d", ch.cmdtype);  
    15.     char buf[1024];  
    16.     sendHeadtobuff(buf, &ch);  
    17.       
    18.     getHeaderfrombuff(buf, &ano);  
    19.     printf("ano.cmdtype = %d/n", ano.cmdtype);  
    20.     //fgets(buf, 1024, stdin);   
    21.     n = Write(sockfd, buf, getHeadlen());  
    22.     if(n == 0)  
    23.     {  
    24.         fprintf(stderr, "write size : 0/n");  
    25.         return ;  
    26.     }  
    27.       
    28.       
    29. }  
    30. int main(int argc,char **argv)  
    31. {  
    32.     int sockfd;  
    33.     struct sockaddr_in srv_addr;  
    34.     if(argc!=2)  
    35.     {  
    36.         fprintf(stderr,"usage : a.out IPaddress/n");  
    37.         exit(1);  
    38.     }  
    39.     sockfd=Socket(AF_INET,SOCK_STREAM,0);  
    40.     bzero(&srv_addr,sizeof(srv_addr));  
    41.     srv_addr.sin_family=AF_INET;  
    42.     srv_addr.sin_port=htons(SRV_PORT);  
    43.     inet_pton(AF_INET,argv[1],&srv_addr.sin_addr);  //remember this   
    44.     Connect(sockfd,(struct sockaddr *)&srv_addr,sizeof(srv_addr));  
    45.     str_cli(sockfd);  
    46.     exit(0);  
    47. }  

    完毕.

  • 相关阅读:
    MyEclipse使用经验总结
    CSDN-markdown编辑器使用简介
    struts2提供的校验器
    JUnit4 中@AfterClass @BeforeClass @after @before的区别对比
    JAVA中文字符编码问题详解 控制台输出
    Statement、PreparedStatement
    struts2 文件上传
    SQL RIGHT JOIN 关键字:语法及案例剖析
    SQL LEFT JOIN 关键字:语法及案例剖析
    SQL INNER JOIN 关键字:语法及案例剖析
  • 原文地址:https://www.cnblogs.com/moonvan/p/2174458.html
Copyright © 2020-2023  润新知