免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
1234下一页
最近访问板块 发新帖
查看: 4245 | 回复: 30
打印 上一主题 下一主题

问关于Godbach兄的通信代码的问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-08-18 16:17 |只看该作者 |倒序浏览
我按照Godbach兄的代码,写了一个关于TCP包计数的程序,只是单纯记录TCP包的数量,
在下载小容量文件<=0.5k左右时可以实现很快的内核用户态交互通信,
但略微大一点的文件1.5k左右就不可以了...或者说效率太低,文件下载不了,想请教下原因
还有在linux里面对文件进行些操作用write(),它所需要的头文件是fctnl.h?
如果是,为什么我编译的时候说 write未定义?
谢谢
代码如下 :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <signal.h>
  5. #include <netinet/tcp.h>
  6. #include <netinet/ip.h>
  7. #include <arpa/inet.h>
  8. #include "libipq.h"
  9. #include <fcntl.h>
  10. #include </home/kide/clamav/libclamav/clamav.h>

  11. #define ETH_HDRLEN 14
  12. #define NF_ACCEPT         1
  13. #define NF_DROP          0


  14. struct ipq_handle *h = NULL;

  15. static void sig_int(int signo)
  16. {
  17.         ipq_destroy_handle(h);
  18.         printf("Exit: %s\n", ipq_errstr());
  19.         exit(0);
  20. }

  21. int main(void)
  22. {
  23.         unsigned char buf[1024];
  24.         /* creat handle*/
  25.         h = ipq_create_handle(0, PF_INET);
  26.         if(h == NULL){
  27.                 printf("%s\n", ipq_errstr());
  28.                 return 0;
  29.         }
  30.         printf("ipq_creat_handle success!\n");
  31.         /*set mode*/
  32.         unsigned char mode = IPQ_COPY_PACKET;
  33.         int range = sizeof(buf);
  34.         int ret = ipq_set_mode(h, mode, range);
  35.         printf("ipq_set_mode: send bytes =%d, range=%d\n", ret, range);
  36.        
  37.         /*register signal handler*/
  38.         signal(SIGINT, sig_int);

  39.         /*read packet from kernel*/
  40.         int status;
  41.         struct nlmsghdr *nlh;
  42.         ipq_packet_msg_t *ipq_packet;
  43.         int count = 0;
  44.        
  45.         while(1){
  46.                 status = ipq_read(h, buf, sizeof(buf));
  47.                 if(status > sizeof(struct nlmsghdr))
  48.                 {
  49.                         nlh = (struct nlmsghdr *)buf;
  50.                         ipq_packet = ipq_get_packet(buf);
  51.                         printf("recv bytes =%d, nlmsg_len=%d, indev=%s, datalen=%d, packet_id=%x\n", status, nlh->nlmsg_len,
  52.                                         ipq_packet->indev_name,  ipq_packet->data_len, ipq_packet->packet_id);
  53.                         unsigned char payload[65532];
  54.                         memset(payload, 0x00, sizeof(payload));
  55.                         memcpy(payload + ETH_HDRLEN, ipq_packet->payload, ipq_packet->data_len);
  56.                         /*display packet data in hex including 14 bytes of eth hdr(set by 0x00)*/
  57.                         int i;
  58.                         for(i = 0; i < ipq_packet->data_len + ETH_HDRLEN; i++){
  59.                                 if(i%16 == 0)
  60.                                         printf("00%.2x:  ", i);
  61.                                 printf("%.2x ", payload[i]);
  62.                                 if(i % 16 == 15)
  63.                                         printf("\n");
  64.                         }
  65.                         printf("\n");
  66.                 }
  67.                 struct iphdr * iph = (struct iphdr *) ipq_packet->payload;
  68.                 if( iph->protocol == 6)
  69.                 {
  70.                         //int fd = open("/home/kide/temp",O_WRONLY);
  71.                         unsigned char *data= ipq_packet->payload + sizeof(struct iphdr) + sizeof(struct tcphdr);
  72.                         //long int num=write(fd,data,ipq_packet->data_len-sizeof(struct iphdr) - sizeof(struct tcphdr));
  73.                         printf("%dbytes has been written \n",num);
  74.                         if(ipq_set_verdict(h, ipq_packet->packet_id, NF_ACCEPT,ipq_packet->data_len,ipq_packet->payload) !=-1)
  75.                         count++;
  76.                         printf("%dTCP success\n",count);
  77.                 }
  78.                 else
  79.                 {
  80.                         if(ipq_set_verdict(h, ipq_packet->packet_id, NF_ACCEPT,ipq_packet->data_len,ipq_packet->payload) !=-1)
  81.                         printf("OTHERS        success\n");
  82.                 }
  83.                
  84.         }
  85.         return 0;
  86. }
复制代码

[ 本帖最后由 Godbach 于 2009-8-18 16:38 编辑 ]

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
2 [报告]
发表于 2009-08-18 16:26 |只看该作者
                        for(i = 0; i < ipq_packet->data_len + ETH_HDRLEN; i++){
                                if(i%16 == 0)
                                        printf("00%.2x:  ", i);
                                printf("%.2x ", payload);
                                if(i % 16 == 15)
                                        printf("\n");
                        }


这段代码是显示报文内容的,每个包都打印到终端上,肯定效率不会搞了。你把这段代码屏蔽掉,然后试一下。

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
3 [报告]
发表于 2009-08-18 16:27 |只看该作者
我的示例中只是为了演示,所以把报文的全部内容都打出来了,你需要根据自己的实际情况,来选择打印哪些内容。

论坛徽章:
0
4 [报告]
发表于 2009-08-18 16:34 |只看该作者

回复 #2 Godbach 的帖子

改了之后还是不能下载... 我下载300多字节的文件才传了4个TCP包,但是下这个1.7KB的文件却收了500多数据包,还没有下载成功,浏览器未跳出下载窗口,这是什么原因?

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
5 [报告]
发表于 2009-08-18 16:38 |只看该作者
你这里对报文做了计数之后,就告诉内核ACCEPT了吗?

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
6 [报告]
发表于 2009-08-18 16:39 |只看该作者
帮你编辑了一下代码,这样看起来舒服些。

论坛徽章:
0
7 [报告]
发表于 2009-08-18 17:34 |只看该作者

回复 #5 Godbach 的帖子

从代码上看,应该是先告诉内核ACCEPT计数
怎么作出那个CODE的效果?

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
8 [报告]
发表于 2009-08-18 18:18 |只看该作者
增加统计计数,然后告诉内核ACCEPT啊。你指的CODE效果是什么意思

论坛徽章:
0
9 [报告]
发表于 2009-08-18 18:44 |只看该作者

回复 #8 Godbach 的帖子

就是你编辑我帖子中代码后代码会在框中显示
为什么要先计数?

论坛徽章:
0
10 [报告]
发表于 2009-08-18 18:49 |只看该作者
感觉数据包从核心态到用户态,返回核心态,效率太低下了吧?
还有每次用open打开文件,用write进行写的时候是不是从文件最后开始写?
我的temp文件只能达到987字节,不知道为什么,这样的大小显然不能满足我的要求....

[ 本帖最后由 kidexp 于 2009-8-18 18:57 编辑 ]
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP