zoukankan      html  css  js  c++  java
  • 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. }  

    完毕.

  • 相关阅读:
    WHERE col1=val1 AND col2=val2;index exists on col1 and col2, the appropriate rows can be fetched directly
    MySQL 交集 实现方法
    MBProgressHUD的使用
    Xcode4 使用 Organizer 分析 Crash logs(转)
    SimpleXML 使用详细例子
    PHP的XML Parser(转)
    iPhone,iPhone4,iPad程序启动画面的总结 (转)
    Pop3得到的Email 信件格式介绍
    yii总结
    隐藏Tabbar的一些方法
  • 原文地址:https://www.cnblogs.com/moonvan/p/2174458.html
Copyright © 2011-2022 走看看