- 論壇徽章:
- 0
|
本帖最后由 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的方式是否可行?
附代碼如下:- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #include <unistd.h>
- #if 1
- #include "ptype.h"
- #include "rbtree.h"
- //#include "read.h"
- #include "parse.h"
- #endif
- /*
- *receive data as recv port
- */
- int insertImsi(struct rb_root *root, struct clientNode_s *__clientNode, charsCmp_t cmp)
- {
- struct rb_node **new = &(root->rb_node), *parent = NULL;
- /* Figure out where to put new node */
- while (*new)
- {
- //struct mytype *this = container_of(*new, struct mytype, node);
- struct clientNode_s *clientNode = container_of(*new, struct clientNode_s, node);
- int result = cmp(__clientNode->clientImsi, clientNode->clientImsi);
- parent = *new;
- if (result < 0)
- new = &((*new)->rb_left);
- else if (result > 0)
- new = &((*new)->rb_right);
- else
- return 0;
- }
- /* Add new node and rebalance tree. */
- rb_link_node(&(__clientNode->node), parent, new);
- rb_insert_color(&(__clientNode->node), root);
- return 1;
- }
- int insertClientId(struct rb_root *root, struct clientNode_s *__clientNode, cmp_t cmp)
- {
- struct rb_node **new = &(root->rb_node), *parent = NULL;
- /* Figure out where to put new node */
- while (*new)
- {
- //struct mytype *this = container_of(*new, struct mytype, node);
- struct clientNode_s *clientNode = container_of(*new, struct clientNode_s, node);
- int result = cmp(__clientNode->clientId, clientNode->clientId);
- parent = *new;
- if (result < 0)
- new = &((*new)->rb_left);
- else if (result > 0)
- new = &((*new)->rb_right);
- else
- return 0;
- }
- /* Add new node and rebalance tree. */
- rb_link_node(&(__clientNode->node), parent, new);
- rb_insert_color(&(__clientNode->node), root);
- return 1;
- }
- struct clientNode_s *searchClientId(struct rb_root *root, unsigned int __clientId, cmp_t cmp)
- {
- struct rb_node *node = root->rb_node;
- while (node)
- {
- struct clientNode_s *clientNode = container_of(node, struct clientNode_s, node);
- int result = cmp(__clientId, clientNode->clientId);
- if (result < 0)
- node = node->rb_left;
- else if (result > 0)
- node = node->rb_right;
- else
- return clientNode;
- }
- return NULL;
- }
- struct clientNode_s *searchImsi(struct rb_root *root, char* __imsi, charsCmp_t cmp)
- {
- struct rb_node *node = root->rb_node;
- while (node)
- {
- struct clientNode_s *clientNode = container_of(node, struct clientNode_s, node);
- int result = cmp(__imsi, clientNode->clientImsi);
- if (result < 0)
- node = node->rb_left;
- else if (result > 0)
- node = node->rb_right;
- else
- return clientNode;
- }
- return NULL;
- }
- unsigned int uicmp(const unsigned int __arg1, const unsigned int __arg2)
- {
- return (__arg1 - __arg2);
- }
- #if 1
- #if 1
- int charsCmp(const char* __arg1, const char* __arg2)
- {
- int i;
- for(i = 0; ((i < __arg1[0]) && (i < CIMSI_LEN)); i++) /** Note: arg1[0] is the length of string **/
- {
- if(__arg1[i] != __arg2[i])
- {
- return __arg1[i] - __arg2[i];
- }
- }
- return 0;
- }
- #else
- unsigned int charsCmp(const char* __arg1, const char* __arg2, int __len)
- {
- for(int i = 0; (i < CIMSI_LEN) && (i < __len); i++)
- {
- if(__arg1[i] != __arg2[i])
- {
- return __arg1[i] - __arg2[i];
- }
- }
- return 0;
- }
- #endif
- #else
- unsigned int charsCmp(const char* __arg1, const char* __arg2)
- {
- int i;
- if(__arg1[0] != __arg2[0]) /** 先比較長度 **/
- {
- return __arg1[0] - __arg2[0];
- }
-
- for(i = 1; (i < CIMSI_LEN) && (i < __arg1[0]); i++)
- {
- if(__arg1[i] != __arg2[i])
- {
- return __arg1[i] - __arg2[i];
- }
- }
- return 0;
- }
- #endif
- int main(int argc, char *argv[])
- {
- //int i;
- int sock_fd;
- //int iLen = 0;
- struct sockaddr_in myaddr;
- struct sockaddr_in src_addr;
- struct sockaddr_in dst_addr;
- struct clientNode_s *dstNode;
- struct clientNode_s *srcNode;
- char dstImsi[CIMSI_LEN];
- char srcImsi[CIMSI_LEN];
- char format[CFMAT_LEN];
- //unsigned int dstClientId = 0;
- //unsigned int srcClientId = 0;
- struct rb_root root = RB_ROOT;
- char buf[BUF_LEN];
- char value[BUF_LEN];
- int iStrLen = 0;
- int recv_num;
- int recvlen;
- if(2 > argc)
- {
- printf("argc\n");
- exit(1);
- }
- if(-1 == (sock_fd = socket(PF_INET, SOCK_DGRAM, 0)))
- {
- printf("socket\n");
- exit(2);
- }
- myaddr.sin_family = AF_INET;
- myaddr.sin_port = htons(atoi(argv[1]));
- myaddr.sin_addr.s_addr = htonl(INADDR_ANY);
- if(-1 == bind(sock_fd, (struct sockaddr *)&myaddr, sizeof(struct sockaddr_in)))
- {
- perror("bind");
- exit(1);
- }
- while(1)
- {
- fprintf(stderr, "[%s-%d]receiving ... \n", __FILE__, __LINE__);
- recvlen = sizeof(struct sockaddr_in);
- bzero(buf, BUF_LEN);
- recv_num = recvfrom(sock_fd, (char *)buf, sizeof(buf), 0,
- (struct sockaddr *)&src_addr, (socklen_t *)&recvlen);
- fprintf(stderr, "[%s-%d]received ! \n", __FILE__, __LINE__);
- if(recv_num != -1)
- {
- iStrLen = strlen(buf);
- iStrLen = iStrLen > recv_num? iStrLen:recv_num;
- memcpy(value, buf, iStrLen);
- parsePacketFormatId(value, format);
- memcpy(value, buf, iStrLen);
- parseSrcImsi(value, srcImsi);
- memcpy(value, buf, iStrLen);
- parseDstImsi(value, dstImsi);
- if((strcmp(format, "data-send") == 0) || (strcmp(format, "data-ACK") == 0))
- {
- fprintf(stderr, "[%s-%d]received data !\n", __FILE__, __LINE__);
- //dstNode = searchImsi(&root, srcImsi, strcmp);
- dstNode = searchImsi(&root, dstImsi, strcmp);
- if(NULL != dstNode)
- {
- /** received data and find the destination node, forward data **/
- fprintf(stderr, "[%s-%d]ready to forward data !\n", __FILE__, __LINE__);
- dst_addr.sin_family = AF_INET;
- dst_addr.sin_port = dstNode->port;
- dst_addr.sin_addr.s_addr = inet_addr(dstNode->loginAddr);
- //memcpy(&dst_addr, dstNode->ipAddr, sizeof(dst_addr));
- //int ret = sendto(sock_fd, buf, BUF_LEN, 0, (struct sockaddr *)dstNode->ipAddr, sizeof(struct sockaddr_in));
- int ret = sendto(sock_fd, buf, BUF_LEN, 0, (struct sockaddr *)&dst_addr, sizeof(struct sockaddr_in));
- if(-1 == ret)
- {
- fprintf(stderr, "[%s-%d]send data error !\n", __FILE__, __LINE__);
- exit(2);
- }
- #if 1
- fprintf(stderr, "[%s-%d]forward data from [%s-%s:%u] to [%s-%s:%u]!\n",
- __FILE__, __LINE__,
- srcImsi,
- inet_ntoa(src_addr.sin_addr),
- src_addr.sin_port,
- dstImsi,
- inet_ntoa(dst_addr.sin_addr),
- dst_addr.sin_port);
- #endif
- }
- else
- {
- fprintf(stderr, "[%s-%d]destination[%s] is not on line!\n", __FILE__, __LINE__, dstImsi);
- }
- }
- else if(strcmp(format, "login-request") == 0) /** 登錄請求,記錄信息 **/
- {
- /** received login message **/
- srcNode = searchImsi(&root, srcImsi, strcmp);
- if(NULL == srcNode)
- {
- /** create new node **/
- srcNode = malloc(sizeof(struct clientNode_s));
- if(NULL != srcNode)
- {
- bzero(srcNode, sizeof(struct clientNode_s));
- memcpy(srcNode->clientImsi, srcImsi, CIMSI_LEN);
- memcpy(srcNode->ipAddr, &src_addr, sizeof(src_addr));
- srcNode->clientStatus = STATUS_LGINSUC; /** 進(jìn)入登錄狀態(tài) **/
- insertImsi(&root, srcNode, strcmp);
- fprintf(stderr, "[%s-%d]Client Node[%s-%s:%u] created ok!\n",
- __FILE__, __LINE__,
- srcImsi,
- inet_ntoa(src_addr.sin_addr),
- src_addr.sin_port);
-
- }
- else
- {
- fprintf(stderr, "[%s-%d]malloc error. Client Node[%s] created failed!\n", __FILE__, __LINE__, srcImsi);
- }
- }
- else
- {
- srcNode->clientStatus = STATUS_LGINSUC; /** 進(jìn)入登錄狀態(tài) **/
- memcpy(srcNode->clientImsi, srcImsi, CIMSI_LEN);
- memcpy(srcNode->ipAddr, &src_addr, sizeof(src_addr));
- fprintf(stderr, "[%s-%d]Client[%s-%s:%u] login again !\n",
- __FILE__, __LINE__,
- srcImsi,
- inet_ntoa(src_addr.sin_addr),
- src_addr.sin_port);
- }
- setPacketFormat(buf, "login-ok");
- int ret = sendto(sock_fd, buf, strlen(buf) + 1, 0, (struct sockaddr *)&src_addr, sizeof(struct sockaddr_in));
- if(-1 == ret)
- {
- perror("sendto");
- fprintf(stderr, "[%s-%d]sendto error !!!!!!\n", __FILE__, __LINE__ );
- //exit(2);
- }
- else
- {
- fprintf(stderr, "[%s-%d]send login ACK ok\n", __FILE__, __LINE__ );
- }
- /**
- * store the client [IP:port]
- **/
- strcpy(srcNode->loginAddr, inet_ntoa(src_addr.sin_addr));
- srcNode->port = src_addr.sin_port;
-
- fprintf(stderr, "[%s-%d]Client [%s: %s: %d] login \n",
- __FILE__, __LINE__,
- srcImsi,
- inet_ntoa(((struct sockaddr_in *)(srcNode->ipAddr))->sin_addr),
- ((struct sockaddr_in *)(srcNode->ipAddr))->sin_port);
-
- }
- else if(strcmp(format, "login-out") == 0)
- {
- fprintf(stderr, "[%s-%d]Client[%s] logout!\n", __FILE__, __LINE__, srcImsi);
- }
- else
- {
- fprintf(stderr, "[%s-%d]buf[%s] is unrecognized!!!\n", __FILE__, __LINE__, buf);
- }
- }
- }
- close(sock_fd);
- return 0;
- }
復(fù)制代碼 |
|