亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費注冊 查看新帖 |

Chinaunix

  平臺 論壇 博客 文庫
最近訪問板塊 發(fā)新帖
查看: 5944 | 回復(fù): 2
打印 上一主題 下一主題

求助,一個UDP數(shù)據(jù)轉(zhuǎn)發(fā)問題! [復(fù)制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報告]
發(fā)表于 2013-10-04 12:57 |只看該作者 |倒序瀏覽
本帖最后由 zhanglong71 于 2013-10-04 15:55 編輯

一個轉(zhuǎn)發(fā)網(wǎng)絡(luò)數(shù)據(jù)包的程序,想不通問題出在哪里!請高人指點。

實現(xiàn)的原理如下:
1.使用UDP協(xié)議。
登錄過程如下:
2.客戶端(Client)向轉(zhuǎn)發(fā)服務(wù)器(Server)發(fā)送登錄數(shù)據(jù)包。登錄數(shù)據(jù)包中包括客戶自己的ID號。
3.轉(zhuǎn)發(fā)服務(wù)器(Server)將收到的登錄數(shù)據(jù)包中的客戶ID號及源ip+port記錄下來。
客戶端1向客戶端2發(fā)送數(shù)據(jù)的過程如下:
4.客戶端1向轉(zhuǎn)發(fā)服務(wù)器發(fā)數(shù)據(jù)包,包內(nèi)有源客戶端ID1及目的客戶端ID2。
5.轉(zhuǎn)發(fā)服務(wù)器(Server)將從客戶端收到的數(shù)據(jù)包中提取目的客戶端ID2,以目的客戶端ID2查找客戶端登錄時的ip+port。再將數(shù)據(jù)包發(fā)往此ip+port對應(yīng)的客戶端2。

執(zhí)行一次數(shù)據(jù)傳輸后服務(wù)器端的數(shù)據(jù)如下:
[start.c-213]receiving ...
[start.c-219]received !
[start.c-290]Client Node[22345678901-192.168.1.112:9655] created ok!
[start.c-324]send login ACK ok
[start.c-333]Client [22345678901: 192.168.1.112: 9655] login
[start.c-213]receiving ...
[start.c-219]received !
[start.c-290]Client Node[12345678901-192.168.1.103:7100] created ok!
[start.c-324]send login ACK ok
[start.c-333]Client [12345678901: 192.168.1.103: 7100] login
[start.c-213]receiving ...
[start.c-219]received !
[start.c-236]received data !
[start.c-242]ready to forward data !
[start.c-258]forward data from [12345678901-192.168.1.103:7100] to [22345678901-192.168.1.103:9655]!
[start.c-213]receiving ...
[start.c-219]received !
[start.c-236]received data !
[start.c-242]ready to forward data !
[start.c-258]forward data from [22345678901-192.168.1.112:9655] to [12345678901-192.168.1.112:7100]!
[start.c-213]receiving ...

其中:start.c-333表示客戶端登錄時的ID號及ip:port。
   start.c-258表示數(shù)據(jù)從客戶端1發(fā)往客戶端2時的ID號:ip:port

問題:
  1.比較[start.c-333]與[start.c-258]的信息后發(fā)現(xiàn),登錄時的ip地址與需要轉(zhuǎn)發(fā)數(shù)據(jù)時找到的ip地址不同:
登錄時的節(jié)點信息是“22345678901: 192.168.1.112: 9655”。而轉(zhuǎn)發(fā)需要數(shù)據(jù)時,找到的節(jié)點信息卻是“22345678901-192.168.1.103:9655”,兩者的ip地址不同
似乎[start.c-258]處錯打印了源端的ip地址信息。但找不到哪里有問題。
    2.這種數(shù)據(jù)轉(zhuǎn)發(fā)及從recvfrom()中取得數(shù)據(jù)包的源ip+port的方式是否可行?

附代碼如下:
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <sys/types.h>
  5. #include <sys/socket.h>
  6. #include <netinet/in.h>
  7. #include <arpa/inet.h>
  8. #include <unistd.h>

  9. #if 1
  10. #include "ptype.h"
  11. #include "rbtree.h"
  12. //#include "read.h"
  13. #include "parse.h"
  14. #endif

  15. /*
  16. *receive data as recv port
  17. */

  18. int insertImsi(struct rb_root *root, struct clientNode_s *__clientNode, charsCmp_t cmp)
  19. {
  20.     struct rb_node **new = &(root->rb_node), *parent = NULL;

  21.     /* Figure out where to put new node */
  22.     while (*new)
  23.     {
  24.         //struct mytype *this = container_of(*new, struct mytype, node);
  25.         struct clientNode_s *clientNode = container_of(*new, struct clientNode_s, node);
  26.         int result = cmp(__clientNode->clientImsi, clientNode->clientImsi);

  27.         parent = *new;
  28.         if (result < 0)
  29.             new = &((*new)->rb_left);
  30.         else if (result > 0)
  31.             new = &((*new)->rb_right);
  32.         else
  33.             return 0;
  34.     }

  35.     /* Add new node and rebalance tree. */
  36.     rb_link_node(&(__clientNode->node), parent, new);
  37.     rb_insert_color(&(__clientNode->node), root);

  38.     return 1;
  39. }

  40. int insertClientId(struct rb_root *root, struct clientNode_s *__clientNode, cmp_t cmp)
  41. {
  42.     struct rb_node **new = &(root->rb_node), *parent = NULL;

  43.     /* Figure out where to put new node */
  44.     while (*new)
  45.     {
  46.         //struct mytype *this = container_of(*new, struct mytype, node);
  47.         struct clientNode_s *clientNode = container_of(*new, struct clientNode_s, node);
  48.         int result = cmp(__clientNode->clientId, clientNode->clientId);

  49.         parent = *new;
  50.         if (result < 0)
  51.             new = &((*new)->rb_left);
  52.         else if (result > 0)
  53.             new = &((*new)->rb_right);
  54.         else
  55.             return 0;
  56.     }

  57.     /* Add new node and rebalance tree. */
  58.     rb_link_node(&(__clientNode->node), parent, new);
  59.     rb_insert_color(&(__clientNode->node), root);

  60.     return 1;
  61. }


  62. struct clientNode_s *searchClientId(struct rb_root *root, unsigned  int __clientId, cmp_t cmp)
  63. {
  64.     struct rb_node *node = root->rb_node;
  65.     while (node)
  66.     {
  67.         struct clientNode_s *clientNode = container_of(node, struct clientNode_s, node);
  68.         int result = cmp(__clientId, clientNode->clientId);
  69.         if (result < 0)
  70.             node = node->rb_left;
  71.         else if (result > 0)
  72.             node = node->rb_right;
  73.         else
  74.             return clientNode;
  75.     }   
  76.     return NULL;
  77. }

  78. struct clientNode_s *searchImsi(struct rb_root *root, char* __imsi, charsCmp_t cmp)
  79. {
  80.     struct rb_node *node = root->rb_node;
  81.     while (node)
  82.     {
  83.         struct clientNode_s *clientNode = container_of(node, struct clientNode_s, node);
  84.         int result = cmp(__imsi, clientNode->clientImsi);
  85.         if (result < 0)
  86.             node = node->rb_left;
  87.         else if (result > 0)
  88.             node = node->rb_right;
  89.         else
  90.             return clientNode;
  91.     }   
  92.     return NULL;
  93. }

  94. unsigned int uicmp(const unsigned int __arg1, const unsigned int __arg2)
  95. {
  96.     return (__arg1 - __arg2);
  97. }

  98. #if 1
  99. #if 1
  100. int charsCmp(const char* __arg1, const char* __arg2)
  101. {
  102.     int i;
  103.     for(i = 0; ((i < __arg1[0]) && (i < CIMSI_LEN)); i++)     /** Note: arg1[0] is the length of string **/
  104.     {
  105.         if(__arg1[i] != __arg2[i])
  106.         {
  107.             return  __arg1[i] - __arg2[i];
  108.         }
  109.     }
  110.     return 0;
  111. }
  112. #else
  113. unsigned int charsCmp(const char* __arg1, const char* __arg2, int __len)
  114. {
  115.     for(int i = 0; (i < CIMSI_LEN) && (i < __len); i++)
  116.     {
  117.         if(__arg1[i] != __arg2[i])
  118.         {
  119.             return  __arg1[i] - __arg2[i];
  120.         }
  121.     }
  122.     return 0;
  123. }
  124. #endif

  125. #else
  126. unsigned int charsCmp(const char* __arg1, const char* __arg2)
  127. {
  128.     int i;

  129.     if(__arg1[0] != __arg2[0])      /** 先比較長度 **/
  130.     {
  131.         return  __arg1[0] - __arg2[0];
  132.     }
  133.    
  134.     for(i = 1; (i < CIMSI_LEN) && (i < __arg1[0]); i++)
  135.     {
  136.         if(__arg1[i] != __arg2[i])
  137.         {
  138.             return  __arg1[i] - __arg2[i];
  139.         }
  140.     }
  141.     return 0;
  142. }
  143. #endif

  144. int        main(int argc, char *argv[])
  145. {
  146.         //int i;
  147.         int sock_fd;
  148.         //int iLen = 0;
  149.         struct sockaddr_in myaddr;
  150.         struct sockaddr_in src_addr;
  151.         struct sockaddr_in dst_addr;

  152.     struct clientNode_s *dstNode;
  153.     struct clientNode_s *srcNode;

  154.     char dstImsi[CIMSI_LEN];
  155.     char srcImsi[CIMSI_LEN];
  156.         char format[CFMAT_LEN];
  157.     //unsigned int dstClientId = 0;
  158.     //unsigned int srcClientId = 0;

  159.     struct rb_root root = RB_ROOT;
  160.         char buf[BUF_LEN];
  161.         char value[BUF_LEN];
  162.         int iStrLen = 0;
  163.         int        recv_num;
  164.         int        recvlen;

  165.         if(2 > argc)
  166.         {
  167.                 printf("argc\n");
  168.                 exit(1);
  169.         }

  170.         if(-1 == (sock_fd = socket(PF_INET, SOCK_DGRAM, 0)))
  171.         {
  172.                 printf("socket\n");
  173.                 exit(2);
  174.         }

  175.         myaddr.sin_family = AF_INET;
  176.         myaddr.sin_port = htons(atoi(argv[1]));
  177.         myaddr.sin_addr.s_addr = htonl(INADDR_ANY);

  178.         if(-1 == bind(sock_fd, (struct sockaddr *)&myaddr, sizeof(struct sockaddr_in)))
  179.         {
  180.                 perror("bind");
  181.                 exit(1);
  182.         }

  183.     while(1)
  184.     {
  185.         fprintf(stderr, "[%s-%d]receiving ... \n", __FILE__, __LINE__);
  186.         recvlen = sizeof(struct sockaddr_in);
  187.         bzero(buf, BUF_LEN);
  188.         recv_num = recvfrom(sock_fd, (char *)buf, sizeof(buf), 0,
  189.                 (struct sockaddr *)&src_addr, (socklen_t *)&recvlen);  

  190.         fprintf(stderr, "[%s-%d]received ! \n", __FILE__, __LINE__);
  191.         if(recv_num != -1)
  192.         {
  193.             iStrLen = strlen(buf);
  194.             iStrLen = iStrLen > recv_num? iStrLen:recv_num;

  195.             memcpy(value, buf, iStrLen);
  196.             parsePacketFormatId(value, format);

  197.             memcpy(value, buf, iStrLen);
  198.             parseSrcImsi(value, srcImsi);

  199.             memcpy(value, buf, iStrLen);
  200.             parseDstImsi(value, dstImsi);

  201.             if((strcmp(format, "data-send") == 0) || (strcmp(format, "data-ACK") == 0))
  202.             {
  203.                 fprintf(stderr, "[%s-%d]received data !\n", __FILE__, __LINE__);
  204.                 //dstNode = searchImsi(&root, srcImsi, strcmp);
  205.                 dstNode = searchImsi(&root, dstImsi, strcmp);
  206.                 if(NULL != dstNode)
  207.                 {
  208.                     /** received data and find the destination node, forward data **/
  209.                     fprintf(stderr, "[%s-%d]ready to forward data !\n", __FILE__, __LINE__);

  210.                     dst_addr.sin_family = AF_INET;
  211.                     dst_addr.sin_port = dstNode->port;
  212.                     dst_addr.sin_addr.s_addr = inet_addr(dstNode->loginAddr);
  213.                     //memcpy(&dst_addr, dstNode->ipAddr, sizeof(dst_addr));

  214.                     //int ret = sendto(sock_fd, buf, BUF_LEN, 0, (struct sockaddr *)dstNode->ipAddr, sizeof(struct sockaddr_in));
  215.                     int ret = sendto(sock_fd, buf, BUF_LEN, 0, (struct sockaddr *)&dst_addr, sizeof(struct sockaddr_in));
  216.                     if(-1 == ret)
  217.                     {
  218.                         fprintf(stderr, "[%s-%d]send data error !\n", __FILE__, __LINE__);
  219.                         exit(2);
  220.                     }
  221.                 #if 1
  222.                     fprintf(stderr, "[%s-%d]forward data from [%s-%s:%u] to [%s-%s:%u]!\n",
  223.                             __FILE__, __LINE__,
  224.                             srcImsi,
  225.                             inet_ntoa(src_addr.sin_addr),
  226.                             src_addr.sin_port,
  227.                             dstImsi,
  228.                             inet_ntoa(dst_addr.sin_addr),
  229.                             dst_addr.sin_port);
  230.                 #endif                     
  231.                 }
  232.                 else
  233.                 {
  234.                     fprintf(stderr, "[%s-%d]destination[%s] is not on line!\n", __FILE__, __LINE__, dstImsi);
  235.                 }
  236.             }
  237.             else if(strcmp(format, "login-request") == 0)       /** 登錄請求,記錄信息 **/
  238.             {
  239.                 /** received login message **/
  240.                 srcNode = searchImsi(&root, srcImsi, strcmp);
  241.                 if(NULL == srcNode)
  242.                 {
  243.                     /** create new node **/
  244.                     srcNode = malloc(sizeof(struct clientNode_s));
  245.                     if(NULL != srcNode)
  246.                     {
  247.                         bzero(srcNode, sizeof(struct clientNode_s));
  248.                         memcpy(srcNode->clientImsi, srcImsi, CIMSI_LEN);
  249.                         memcpy(srcNode->ipAddr, &src_addr, sizeof(src_addr));
  250.                         srcNode->clientStatus = STATUS_LGINSUC;  /** 進(jìn)入登錄狀態(tài) **/

  251.                         insertImsi(&root, srcNode, strcmp);

  252.                         fprintf(stderr, "[%s-%d]Client Node[%s-%s:%u] created ok!\n",
  253.                                 __FILE__, __LINE__,
  254.                                 srcImsi,
  255.                                 inet_ntoa(src_addr.sin_addr),
  256.                                 src_addr.sin_port);

  257.                     }
  258.                     else
  259.                     {
  260.                         fprintf(stderr, "[%s-%d]malloc error. Client Node[%s] created failed!\n", __FILE__, __LINE__, srcImsi);
  261.                     }
  262.                 }
  263.                 else
  264.                 {   
  265.                     srcNode->clientStatus = STATUS_LGINSUC;  /** 進(jìn)入登錄狀態(tài) **/

  266.                     memcpy(srcNode->clientImsi, srcImsi, CIMSI_LEN);
  267.                     memcpy(srcNode->ipAddr, &src_addr, sizeof(src_addr));
  268.                     fprintf(stderr, "[%s-%d]Client[%s-%s:%u] login again !\n",
  269.                             __FILE__, __LINE__,
  270.                             srcImsi,
  271.                             inet_ntoa(src_addr.sin_addr),
  272.                             src_addr.sin_port);
  273.                 }

  274.                 setPacketFormat(buf, "login-ok");
  275.                 int ret = sendto(sock_fd, buf, strlen(buf) + 1, 0, (struct sockaddr *)&src_addr, sizeof(struct sockaddr_in));
  276.                 if(-1 == ret)
  277.                 {
  278.                     perror("sendto");
  279.                     fprintf(stderr, "[%s-%d]sendto error !!!!!!\n", __FILE__, __LINE__ );
  280.                     //exit(2);
  281.                 }
  282.                 else
  283.                 {
  284.                     fprintf(stderr, "[%s-%d]send login ACK ok\n", __FILE__, __LINE__ );
  285.                 }
  286.                 /**
  287.                  * store the client [IP:port]
  288.                  **/
  289.                 strcpy(srcNode->loginAddr, inet_ntoa(src_addr.sin_addr));
  290.                 srcNode->port = src_addr.sin_port;
  291.                            
  292.                 fprintf(stderr, "[%s-%d]Client [%s: %s: %d] login \n",
  293.                         __FILE__, __LINE__,
  294.                         srcImsi,
  295.                         inet_ntoa(((struct sockaddr_in *)(srcNode->ipAddr))->sin_addr),
  296.                         ((struct sockaddr_in *)(srcNode->ipAddr))->sin_port);

  297.             }
  298.             else if(strcmp(format, "login-out") == 0)
  299.             {
  300.                 fprintf(stderr, "[%s-%d]Client[%s] logout!\n", __FILE__, __LINE__, srcImsi);
  301.             }
  302.             else
  303.             {
  304.                 fprintf(stderr, "[%s-%d]buf[%s] is unrecognized!!!\n", __FILE__, __LINE__, buf);
  305.             }
  306.         }
  307.     }
  308.         close(sock_fd);

  309.     return  0;
  310. }
復(fù)制代碼

論壇徽章:
0
2 [報告]
發(fā)表于 2013-10-04 17:59 |只看該作者
本帖最后由 zhanglong71 于 2013-10-04 22:12 編輯

在代碼第257-264行之間加入打印節(jié)點信息的語句,兩者顯示的數(shù)據(jù)居然不一樣!
顯示結(jié)果如下:
[start.c-279]ready to forward data !
[22345678901-192.168.1.112:14228]
[start.c-293]forward data from [15343023711-175.1.95.93:25121] to [22345678901-175.1.95.93:14228]!
[22345678901-192.168.1.112:14228]

代碼如下:
  1.       
  2.      printNode(dstNode);
  3.                     fprintf(stderr, "[%s-%d]forward data from [%s-%s:%u] to [%s-%s:%u]!\n",
  4.                             __FILE__, __LINE__,
  5.                             srcImsi,
  6.                             inet_ntoa(src_addr.sin_addr),
  7.                             src_addr.sin_port,
  8.                             dstImsi,
  9.                             inet_ntoa(((struct sockaddr_in *)(dstNode->ipAddr))->sin_addr),
  10.                             ((struct sockaddr_in *)(dstNode->ipAddr))->sin_port);
  11.                     printNode(dstNode);
復(fù)制代碼
中間一次打印的dstNode的內(nèi)容居然與前后兩次的內(nèi)容不一樣!

其中的printNode如下:
  1. void printNode(struct clientNode_s *clientNode)
  2. {
  3.     if(clientNode != NULL)
  4.     {
  5.         printf("[%s-%s:%u]\n",
  6.                 clientNode->clientImsi,
  7.                 inet_ntoa(((struct sockaddr_in *)(clientNode->ipAddr))->sin_addr),
  8.                 ((struct sockaddr_in *)(clientNode->ipAddr))->sin_port);
  9.     }
  10.     else
  11.     {
  12.         printf("null\n");
  13.     }
  14. }
復(fù)制代碼
---------------------------------------------------------------------------------
打印信息不同的問題已解決。很可能是這樣的原因:不能在printf打印語句中兩次調(diào)用inet_ntoa()。
原因是inet_ntoa()會將執(zhí)行的結(jié)果保存在一個靜態(tài)存貯區(qū),并返回此存貯區(qū)的地址。兩次調(diào)用inet_ntoa()后,inet_ntoa()可能返回的都是同一個地址,但其中的內(nèi)容只是最后一次處理后的內(nèi)容。
另一個問題作備忘:手機上的客戶端收不到轉(zhuǎn)發(fā)的數(shù)據(jù)。用wireshark抓包發(fā)現(xiàn),轉(zhuǎn)發(fā)往手機的數(shù)據(jù)包長度已經(jīng)超過1500Bytes。實際的包內(nèi)有用信息大小不超過200。通過計算包內(nèi)字符串長度,并只發(fā)送該長度的數(shù)據(jù),手機上可以正常顯示收到的數(shù)據(jù)。具體修改L250的BUF_LEN改成strlen(buf) + 1。

論壇徽章:
1
技術(shù)圖書徽章
日期:2013-09-17 09:11:51
3 [報告]
發(fā)表于 2013-10-08 16:16 |只看該作者
LZ good boy
您需要登錄后才可以回帖 登錄 | 注冊

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報專區(qū)
中國互聯(lián)網(wǎng)協(xié)會會員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP