Chinaunix

标题: 迎接ChinaUnix九周年庆技术实践之二----C/C++编程大赛!-结果公布! [打印本页]

作者: send_linux    时间: 2010-11-22 14:18
标题: 迎接ChinaUnix九周年庆技术实践之二----C/C++编程大赛!-结果公布!
获奖名单已公布,详情请看:http://bbs.chinaunix.net/thread-1862821-1-1.html

大赛结果及获奖名单公布!

http://bbs.chinaunix.net/thread-1860588-1-1.html

PHP编程大赛的评选结果出来了,请参看。

大赛评选结果已出,敬请关注!:PHP编程大赛隆重启动,PHP开发大挑战
http://bbs3.chinaunix.net/thread-1788191-1-1.html

---------------------------------------------------------
为了庆祝ChinaUnix社区创立9周年,ChinaUnix社区各技术版面将隆重发起各项技术实践活动!

感谢各位为本次活动提供试题和建议的版主和会员:)


大赛背景:

C/C++、Perl、Shell、PHP等ChinaUnix传统程序设计板块一直是CU的技术讨论区的中坚力量。为了庆祝ChinaUnix社区成立九周年,特联合部分出版社举办本次大赛,诚邀各路Coder好手!

第一期PHP程序设计大赛已经完成,相关内容和获奖名单见以下链接:http://bbs.chinaunix.net/thread-1788191-1-1.html

这是第二期,C/C++程序设计大赛,欢迎大家积极参与!

大赛日程:

参赛时间:2010.11.20~2011.01.10

评选时间:2011.01.11~2011.01.18

结果公布:2011.01.19

参赛要求:

参与活动必须为chinaunix论坛注册会员,点击这里注册:http://sso.chinaunix.net/Register

奖项设置及评选办法:

一等奖:3名,赠送ChinaUnix高质量电脑包,获奖者为最先正确完成4道试题的用户,或者某些设计思想获得评委一致赞同的用户。

二等奖:10名,赠送ChinaUnix 9周年限量版ChinaUni秋季长袖T恤,获奖者为最先正确完成两道试题的十名用户。

三等奖:15名,赠送ChinaUnix 9周年 限量版精美纪念真空保温杯,获奖者至少独立完成一道试题,获奖名单由评委按照代码质量和完成试题数目决定。







代码提交:
(1)参赛作品须在规定的初赛代码提交截止日期之前将规定的内容及材料以邮件形式发送到大赛邮箱rmzhou@staff.chinaunix.net。如果代码有变动可以多次发送邮件,以最后邮件提交时间为准。
邮件标题格式为:ChinaUnix论坛C/C++程序设计大赛参赛代码(论坛ID),内容按照各题的需要提交。
(2)你也可以将代码张贴到本活动贴中和大家讨论,但是不作为本次比赛的参赛证据。

注:
参赛选手提交代码必须通过邮件提交,代码版权归CU所有(最后所有的参赛者代码将公布在CU论坛供大家学习和参考)
严禁抄袭,一经发现,取消评选资格;
代码类似,以最后提交时间为准,取最早发布或者修改时间者为优秀



活动细则:

因为本次大赛的题目可能要求不一,每题的要求请看清!

(1)代码规范:使用标准C语言,采用编程标准可以使项目更加顺利地完成。
(2)性能:应用程序运行正常,可以执行用户或客户所需的所有任务,并不意味着程序在任何方面都是完美的,更高的运行性能才能我们所追求的。
(3)简洁:写代码是一种艺术。除了正确的缩进、大小写、命名规则之外,请时刻牢记爱因斯坦的名言--简单就是美。
(4)每位会员可以发表多个代码,以最高评价为准,不可重复获奖;
(5)提交代码参赛的同时,需附相关系统环境及编译环境说明(推荐Linux kernel 2.6.30及以上版本,gcc 4.32及以上)

大赛评委:

cugb_cat:ChinaUnix论坛C/C++版版主,工作主要涉及分布式系统、数据库系统等研发和运营工作。

duanjigang:目前就职于北京一家网络安全公司,5年linux下C/C++开发经验,工作主要涉及网络通讯,终端安全方面。业余做一些开源和LAMP架构方面的开发。

dreamice:资深网络安全产品架构师,在内核开发和网络安全方面有雄厚技术功底,另外也涉猎嵌入式产品开发等方面,目前就职于国内一家知名网络安全公司,任产品经理及开发经理。

Godbach:ChinaUnix 论坛内核源码版版主,从事内核及网络安全的相关开发工作。欢迎大家来内核源码版交流内核相关的各种技术问题。

大赛试题:

试题一:
开发一个域名批量查询程序,文本文件data.txt中存储着N个域名,每行一个,
要求程序从该文件中读取域名数据,然后获取该域名对应的IP地址列表.比如
文件内容为:
www.126.com
www.132321321.com
www.baidu.com
输出格式为:
域名
IP个数
IP1
IP2
...
例如,上面的例子文件中的输出结果为:

www.126.com
1
121.20.3.105
www.132321321.com
0
www.baidu.com
3
212.32.4.211
10.52.32.32
102.31.0.91


评判标准:
我们将会采用N组文件进行测试
优秀的评判标准为:1处理时占用时间短 2运行时占用最大内存小


试题二:
开发一个报文处理程序,捕获指定网口接收的数据包,统计每个会话(五元组,sip,dip,sport,dport,protocol)的流量:字节数,报文数。测试目标,以处理性能和统计精确度为准。


试题三:
对输入进行从小到大排序,然后输出,输入第一行为case数量,第二行起每行是由空格隔开的一组数字,第一个数字是本case中需要排序的数字的数量,后面是要被排序的数字。
输入例子:
2
5 2 9 3 48 1
9 1 0 8 4 5 19 48 2232 112
输出:
1 2 3 9 48
0 1 4 5 8 19 48 112 2232

提示:注意可利用多核特性


试题四:
实现关系表的增删改查功能:
功能需求:关系表,即数据库中数据的表示方式,使用二维行列表示,请实现创建表(create)、删除表(drop)、插入行(insert)、删除行(delete)、修改某些行中的某些字段(update)、查询(select);
限制:表的最大列数不超过255列,最大行数的数量级为百万级,列类型均为int型,表中索引最大数量为16个,
输入:从标准输入输入,第一行为命令字,包括create/drop/insert/delete/update/select六种,当命令字是create时,第二行表示表中包含的列数,这些列由0 -- n-1标识,第三行是一组由空格隔开的数字,表示以这些数字标识的列上有索引,数字的数量不会超过16个或者表的列数;当命令字是drop时,表示将表删除;当命令字是insert时,第二行是一个数字,表示从下一行起要插入到表中的行数,第三行起,每行是一组由空格隔开的数字,数字的数量为表的列数;命令字是delete时,第二行是一个数字,表示后续需要delete的case的数量,每个case一行,第三行起,每行为一些由删除条件组成的case,格式为:no或者列序号1 > num1 and ( 列序号2 < num2 or 列序号3 >= num3 ) and 列序号4 <= num4 and 列序号5 = num5 and 列序号6 != num6,no表示没有条件,即,匹配所有行,条件的组合包含and和or运算,比较运算符包括> < >= <= = !=,由()括起的部分优先级高于未被括起的部分,()不会嵌套,字元之间均有空格隔开;当命令字为update时,第二行为case数量,每个case包括两行,第一行表示要修改的列以及要修改成的值,第二行为过滤条件(与delete的条件格式相同),每个case的第一行的格式为:列序号1 = num1 , 列序号2 = 列序号2 + num2 , 列序号3 = 列序号4 + num3,进行运算只有+和-,逗号分割各个要修改的列;命令字为select时,第二行是后续case数量,第三行起,每行的格式与delete命令字的条件格式相同。
输出:输出到标准输出,只有select命令字有输出,每个select的输入case的输出格式为,第一行为该case后续输出的行数,第二行起,每行是一组由空格隔开的数字,数字的数量与表的列数量相同,输出的各行是按照从第一个字段到最后一个字段升序排列的;

输入例子:
create
5
1 3 4
insert
3
1 2 3 4 5
10 11 12 13 14
100 101 102 103 104
update
1
0 = 4 , 2 = 2 + 100 , 3 = 4 + 1000
1 > 10 and 1 < 100 and ( 2 > 5 or 2 < 1 )
select
2
no
no
delete
1
no
drop
上述输入的输出:
3
1 2 3 4 5
4 11 112 1014 14
100 101 102 103 104
3
1 2 3 4 5
4 11 112 1014 14
100 101 102 103 104

提示:进行update操作时请注意Halloween Problem

提示:本题的运行及编译环境:

Linux,2.6.30内核,4核CPU,CPU主频2.0G,8G内存,x86_64,gcc4.1,pthread,请注明编译参数

在输出正确的情况下,考察指标:1、速度快;2、占用内存少;3、valgrind给出的结果显示无错误和内存泄漏

作者: prolj    时间: 2010-11-22 16:15
评委不是我
作者: 克拉玛依    时间: 2010-11-22 20:31
楼上,你写一个呀
作者: rubylc_unix    时间: 2010-11-22 22:06
栈桌
作者: expert1    时间: 2010-11-23 09:29
顶起,mark之,坐观高手论道
作者: 光速    时间: 2010-11-23 09:50
顶起。
作者: scutan    时间: 2010-11-23 10:57
支持,学习学习。
作者: ziggler    时间: 2010-11-23 10:58
支持
作者: starzhestarzhe    时间: 2010-11-23 11:15
这个比php那个要废点脑子,

第一期PHP程序设计大赛已经完成,相关内容和获奖名单见以下链接:http://bbs.chinaunix.net/thread-1788191-1-1.html


这个结果还没出来好不好
作者: send_linux    时间: 2010-11-23 11:23
支持,学习学习。
scutan 发表于 2010-11-23 10:57



   
顶起,mark之,坐观高手论道
expert1 发表于 2010-11-23 09:29



作为现任版主和将来的实习版主,二位应当以实际行动支持一下!
作者: c/unix    时间: 2010-11-23 12:07
提示: 作者被禁止或删除 内容自动屏蔽
作者: duanjigang    时间: 2010-11-23 13:19
怎么都灌水没人回帖?
作者: lkk2003rty    时间: 2010-11-23 14:06
同占座。。。回去慢慢答题。。。
作者: chrome029    时间: 2010-11-23 14:17
mark,回去答题。
作者: michael1983    时间: 2010-11-23 15:37
必须得支持
作者: ouyxia    时间: 2010-11-23 15:54
偶来参观的。。。
作者: mirnshi    时间: 2010-11-23 18:17
域名批量查询程序,做域名解析程序吗?那得需要熟悉dns协议了,UDP的太简单了,最好弄个udp+tcp的,增加难度,且只能使用socket,禁止使用现成库。网络程序的速度依赖于网络呀,难道评委自己做了dns服务器?{:3_189:}{:3_189:}{:3_189:}
作者: dreamice    时间: 2010-11-23 18:35
支持!大家都热烈的支持起来!
作者: cangt    时间: 2010-11-23 18:39
无条件支持
作者: duanjigang    时间: 2010-11-23 18:56
域名批量查询程序,做域名解析程序吗?那得需要熟悉dns协议了,UDP的太简单了,最好弄个udp+tcp的,增加难度 ...
mirnshi 发表于 2010-11-23 18:17



    呵呵,这个问题考虑到了,为了尽可能减小网络引起的问题,可以在同一台主机上测试,相对而言,网络能稳定点吧?
如果大家要求更高,可以考虑搞一台DNS服务器,进行测试。
作者: jieyuan_cg    时间: 2010-11-23 19:05
占个座先……
作者: angle4    时间: 2010-11-23 20:05
顶 ~~
作者: renxiao2003    时间: 2010-11-23 22:08
支持,抽空答一下。
作者: LaoLiulaoliu    时间: 2010-11-23 22:37
为了锻炼自我,同时支持CU论坛,我很费力的做了一题,代码太烂,请随意批评。

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <netdb.h>
  4. #include <arpa/inet.h>
  5. #define LENGTH 0x40

  6. int main()
  7. {
  8.         FILE *fp;
  9.         char **pptr;
  10.         char chstr[16], buf[LENGTH];
  11.         struct hostent *host_ent;

  12.         fp = fopen("data.txt", "r");
  13.         if (fp == NULL)
  14.         {
  15.                 printf("data.txt don't exist in current directory.\n");
  16.                 return 0;
  17.         }

  18.         do
  19.         {
  20.                 if ( NULL == fgets(buf , LENGTH, fp) )
  21.                         break;
  22.                 printf("%s", buf);
  23.                 buf[strlen(buf)-1] = 0x0;

  24.                 if ( !(host_ent = gethostbyname(buf)) )
  25.                 {
  26.                         printf("Error occur when querying the IP.\n");
  27.                         fclose(fp);
  28.                         return -1;
  29.                 }
  30.                 pptr = host_ent->h_addr_list;
  31.                 int i;
  32.                 char iplist[1024] = {0};
  33.                 for (i = 0; *pptr != NULL; pptr++)
  34.                 {
  35.                         inet_ntop(host_ent->h_addrtype, *pptr, chstr, sizeof(chstr));
  36.                         strncat(iplist, chstr, strlen(chstr));
  37.                         iplist[strlen(iplist)] = 0xa;
  38.                         ++i;
  39.                 }
  40.                 printf("%d\n%s", i, iplist);

  41.         } while (1);

  42.         fclose(fp);
  43.         return 0;
  44. }
复制代码
Linux 2.6.32, gcc 4.4.5
作者: ecjtubaowp    时间: 2010-11-23 23:31
支持,好好做做。
作者: linux初学三月    时间: 2010-11-24 00:04
域名批量查询程序,做域名解析程序吗?那得需要熟悉dns协议了,UDP的太简单了,最好弄个udp+tcp的,增加难度 ...
mirnshi 发表于 2010-11-23 18:17



    我都不会做一道,这还叫简单啊
作者: mirnshi    时间: 2010-11-24 00:09
回复 24# LaoLiulaoliu

1. 至少要多线程,单线程没有取胜的希望
2. feof?
。。。
作者: mirnshi    时间: 2010-11-24 00:09
回复 26# linux初学三月

所以需要学习
作者: surpass_li    时间: 2010-11-24 09:16
学习
作者: heut2009    时间: 2010-11-24 09:54
占座
作者: duanjigang    时间: 2010-11-24 10:24
为了锻炼自我,同时支持CU论坛,我很费力的做了一题,代码太烂,请随意批评。Linux 2.6.32, gcc 4.4.5
LaoLiulaoliu 发表于 2010-11-23 22:37



    谢谢您的第一个程序!
我运行了下,效果很不错,不过有几个建议给你提下,希望能改进,以获得更好的评价。

第一: 其中一个查询出错时,程序不应该立即退出吧,还应该接着查询其它的。
第二: 代码对数据校验做一下,有些空行还是要扔掉的,呵呵。
第三: 功能实现上 gethostbyname方法能做到了,但是您是否考虑过开发个多线程的应用,还有,多线程情况下用gethostbyname是不是很好?
      呵呵,在网上看到一段文字,仅供参考,很期望您或者别人能做出更好的改进版。首先对这第一个贴表示赞赏,鼓励!!

以下是参考文字:
http://www.codelast.com/?p=221
关于gethostbyname在多线程环境下的阻塞问题
2010年9月14日 由 learnhard 留言 &raquo; 转自:http://read.newbooks.com.cn/info/196629.html

Unix/Linux下的gethostbyname函数常用来向DNS查询一个域名的IP地址。 由于DNS的递归查询,常常会发生gethostbyname函数在查询一个域名时严重超时。而该函数又不能像connect和read等函数那样通过setsockopt或者select函数那样设置超时时间,因此常常成为程序的瓶颈。有人提出一种解决办法是用alarm设置定时信号,如果超时就用setjmp和longjmp跳过gethostbyname函数(这种方式我没有试过,不知道具体效果如何)。


在多线程下面,gethostbyname会一个更严重的问题,就是如果有一个线程的gethostbyname发生阻塞,其它线程都会在gethostbyname处发生阻塞。我在编写爬虫时也遇到了这个让我疑惑很久的问题,所有的爬虫线程都阻塞在gethostbyname处,导致爬虫速度非常慢。在网上google了很长时间这个问题,也没有找到解答。今天凑巧在实验室的googlegroup里面发现了一本电子书”Mining the Web – Discovering Knowledge from Hypertext Data”,其中在讲解爬虫时有下面几段文字:

Many clients for DNS resolution are coded poorly.Most UNIX systems provide an implementation of gethostbyname (the DNS client API—application program interface), which cannot concurrently handle multiple outstanding requests. Therefore, the crawler cannot issue many resolution requests together and poll at a later time for completion of individual requests, which is critical for acceptable performance. Furthermore, if the system-provided client is used, there is no way to distribute load among a number of DNS servers. For all these reasons, many crawlers choose to include their own custom client for DNS name resolution. The Mercator crawler from Compaq System Research Center reduced the time spent in DNS from as high as 87% to a modest 25% by implementing a custom client. The ADNS asynchronous DNS client library is ideal for use in crawlers.

In spite of these optimizations, a large-scale crawler will spend a substantial fraction of its network time not waiting for Http data transfer, but for address resolution. For every hostname that has not been resolved before (which happens frequently with crawlers), the local DNS may have to go across many network hops to fill its cache for the first time. To overlap this unavoidable delay with useful work, divfetching can be used. When a page that has just been fetched is parsed, a stream of HREFs is extracted. Right at this time, that is, even before any of the corresponding URLs are fetched, hostnames are extracted from the HREF targets, and DNS resolution requests are made to the caching server. The divfetching client is usually implemented using UDP  instead of TCP, and it does not wait for resolution to be completed. The request serves only to fill the DNS cache so that resolution will be fast when the page is actually needed later on.

大意是说unix的gethostbyname无法处理在并发程序下使用,这是先天的缺陷是无法改变的。大型爬虫往往不会使用gethostbyname,而是实现自己独立定制的DNS客户端。这样可以实现DNS的负载平衡,而且通过异步解析能够大大提高DNS解析速度。DNS客户端往往用UDP实现,可以在爬虫爬取网页前提前解析URL的IP。文章中还提到了一个开源的异步DNS库adns,主页是http://www.chiark.greenend.org.uk/~ian/adns/

从以上可看出,gethostbyname并不适用于多线程环境以及其它对DNS解析速度要求较高的程序

作者: send_linux    时间: 2010-11-24 10:37
谢谢您的第一个程序!
我运行了下,效果很不错,不过有几个建议给你提下,希望能改进,以获得更 ...
duanjigang 发表于 2010-11-24 10:24



    真给力......
作者: duanjigang    时间: 2010-11-24 10:58
真给力......
send_linux 发表于 2010-11-24 10:37



    我没法子给这位朋友加分啊
作者: DNFCF    时间: 2010-11-24 11:01
对我来说,太难了。。。。
作者: zhangsuozhu    时间: 2010-11-24 11:52
第二题要求写用户态的还是写内核态的?内核态的,可以实现零考贝的。用户状的,呵呵。比内核态的要慢的。
作者: smali    时间: 2010-11-24 14:43
评选时间:2011.01.11~2010.01.18  ??
作者: send_linux    时间: 2010-11-24 15:02
评选时间:2011.01.11~2010.01.18  ??
smali 发表于 2010-11-24 14:43



    修改好了,谢谢您的提醒啊,欢迎参加我们的比赛啊,呵呵
作者: send_linux    时间: 2010-11-24 15:03
第二题要求写用户态的还是写内核态的?内核态的,可以实现零考贝的。用户状的,呵呵。比内核态的要慢的。
zhangsuozhu 发表于 2010-11-24 11:52



    老兄也可以亲自参加一下哈,重在参与嘛,多和大家交流交流。
作者: lonerwolf    时间: 2010-11-24 19:41
{:3_182:}练练手
作者: kingbigeast    时间: 2010-11-24 22:32
表示除了第三题都不会做。
作者: changzhiwin    时间: 2010-11-25 09:56
回复 1# send_linux
请问获奖的作品会公开吗?
作者: send_linux    时间: 2010-11-25 10:14
回复  send_linux
请问获奖的作品会公开吗?
changzhiwin 发表于 2010-11-25 09:56



    会的。
作者: LaoLiulaoliu    时间: 2010-11-25 22:28
本帖最后由 LaoLiulaoliu 于 2010-11-26 08:55 编辑

回复 31# duanjigang


你提出的3点很好,前2点都很简单,多线程的模型也不难。
问题在于这个adns。我发现adns没有doc,没有example,只有src代码,还没来得及看。
1.我实现了一下,但是每一个地址只能查出来一个。结果比gethostbyname差多了。
2.www.163.com查询的时候总是有问题,我看返回状态是101(adns_s_prohibitedcname, 说服务器配置不允许CNAME,我配置adns_qf_cname_loose来查询也不行,但是gethostbyname就可以查询到,还返回好几个呢)。
3.对于异步,我开几个线程都来初始化,然后查询就叫异步吗?还是说对于每个线程,他们的查询都是不相关的(那就得用序列号来确认哪个包是哪个线程的了吧)?
4.adns网页说可以把/etc/resolv.conf 屏蔽掉,那么他拿什么DNS服务器查询呢?
4.non-blocking 这个东西adns实现了吗?他如果不要阻塞,那就得设置超时,然后过一会再查询。是这样吗?
5.这个项目是否早就停止了?我看adns.h里面只有到2006年,而且网页里面说的Forthcoming 的东西一直也没有人管。

不知道是否能在比赛时问这么多问题?请多多包涵。
作者: dreamice    时间: 2010-11-25 22:56
回复 43# LaoLiulaoliu


    adns可以研究研究,如果单纯的用gethostbyname来实现,又不能利用多线程提高效率的话,本题也没有多大的含金量了,所以还希望大家能充分发挥各自的智慧,以探讨出一个更高效的解决方案。
作者: LaoLiulaoliu    时间: 2010-11-26 08:42
回复 44# dreamice


    那么自己构造数据包,然后用libnet发包怎么样?
作者: tkchks    时间: 2010-11-26 10:11
学习..
作者: mirnshi    时间: 2010-11-26 10:46
回复  dreamice


    那么自己构造数据包,然后用libnet发包怎么样?
LaoLiulaoliu 发表于 2010-11-26 08:42


为啥用libnet? udp直接发送就是了
作者: cugb_cat    时间: 2010-11-26 10:51
回复 47# mirnshi

可以啊,发挥想象力,条条大路通罗马。
作者: mirnshi    时间: 2010-11-26 11:20
自己构建dns请求,解析dns不是什么难事。n年前,我在内核就做过了。拷一段dns请求体
        u_char dnsdata[] = {
            /* HEADER */
            0x4c, 0x42, /* ID */
            0x01, 0x00, /* QR|OC|AA|TC|RD -  RA|Z|RCODE  */
            0x00, 0x01, /* QDCOUNT */
            0x00, 0x00, /* ANCOUNT */
            0x00, 0x00, /* NSCOUNT */
            0x00, 0x00, /* ARCOUNT */
            4, 't','i','m','e',
            7, 'w','i','n','d','o','w','s',
            3, 'c','o','m',
            0,                /* QNAME */
            0x00,0x01,  /* QTYPE A record */
            0x00,0x01   /* QCLASS: IN */
           /* lookup root servers?, use this: */
            /*    0x00,        QNAME:  empty */
            /*    0x00, 0x02,  QTYPE:  a authorative name server */
            /*    0x00, 0x01   QCLASS: IN */
          };
作者: 贺兰云天    时间: 2010-11-26 11:26
支持啊!!!
构造DNS请求报文这个应用层也比较好做的,大家支持喔
作者: Kabie    时间: 2010-11-26 13:13
....话说第一题那个例子IP是乱给的吧。。。
作者: cugb_cat    时间: 2010-11-26 15:27
回复 51# Kabie

只是个例子,呵呵。
作者: Kabie    时间: 2010-11-26 15:37
。。。呃……我这边会被导到114上面去……实际上没有0的。。。{:3_194:}
作者: lygxy    时间: 2010-11-28 02:47
占座,偶也要参加,虽然哦很菜
作者: herecomes    时间: 2010-11-28 18:50
mark
作者: yifangyou    时间: 2010-11-28 19:31
我要参加,已经做了2题了,不过题目真的很难
作者: starT_T    时间: 2010-11-29 12:44
我来看看 顶起啊
作者: renxiao2003    时间: 2010-11-29 15:19
已经做了一个。凑合准确。晚上发给茂哥。呵呵。
作者: yyxl    时间: 2010-11-29 16:06
支持,学习学习。
作者: renxiao2003    时间: 2010-11-29 22:04
茂哥,发送给你了啊。呵呵。
作者: renenglish    时间: 2010-11-29 22:44
学习!
作者: surpass_li    时间: 2010-11-30 09:13
帮顶,都不会呀
作者: send_linux    时间: 2010-11-30 09:21
茂哥,发送给你了啊。呵呵。
renxiao2003 发表于 2010-11-29 22:04



    已经收到,谢谢参与!
作者: renxiao2003    时间: 2010-11-30 10:42
回复 63# send_linux


    C太难了。呵呵。一直都比较头痛。除了这个题,其它的是根本不会了啊。这个是凑合做上来的。呵呵。
作者: ddddxx6    时间: 2010-11-30 22:22
发送答案给send_linux
作者: scwanghongying    时间: 2010-11-30 22:50
提交答案。
作者: send_linux    时间: 2010-12-01 08:31
发送答案给send_linux
ddddxx6 发表于 2010-11-30 22:22



   

提交答案。
scwanghongying 发表于 2010-11-30 22:50



    两位的代码已经收到,谢谢二位的参与!

大家都只做第三题啊,呵呵
作者: surpass_li    时间: 2010-12-01 11:29
怎么提交代码呀,谢谢
作者: rubylc_unix    时间: 2010-12-01 12:38
回复 68# surpass_li


    第一贴上面有阿,发邮件!!
作者: surpass_li    时间: 2010-12-01 12:53
回复 69# rubylc_unix


    找到了,谢谢,晚上发代码:)
作者: pincs    时间: 2010-12-02 08:47
我也占个位先
作者: surpass_li    时间: 2010-12-02 09:27
回复  surpass_li


    第一贴上面有阿,发邮件!!
rubylc_unix 发表于 2010-12-01 12:38



    代码已经发给您了
作者: renxiao2003    时间: 2010-12-02 14:00
第一题难度也不高。已基本完成。晚上提交。
作者: renxiao2003    时间: 2010-12-02 21:48
提交了第一题答案,在cygwin环境下通过。
不知道在其他环境下会不会有问题啊。
作者: renxiao2003    时间: 2010-12-03 09:38
二四题的难度太高了。都没找到参考资料。难哦。
作者: jhui66    时间: 2010-12-03 10:06
可惜不太懂PHP
作者: surpass_li    时间: 2010-12-03 14:01
努力查找资料 域名取IP 做出来了,晚上提交代码:)
作者: renxiao2003    时间: 2010-12-03 14:22
回复 77# surpass_li


    厉害。哥昨天就提交代码了。你比我慢一步。
作者: xiaocong004    时间: 2010-12-03 14:38
看起来不难,做起来,想做好还需要费一番脑子。
作者: heut2009    时间: 2010-12-03 16:42
本帖最后由 heut2009 于 2010-12-03 16:45 编辑

第二题
写出个有bug的半成品,望各位给指点指点,给点意见,我好想拿个奖啊。


  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<sys/socket.h>
  4. #include<netinet/in.h>
  5. #include<linux/if_ether.h>
  6. #include<signal.h>
  7. #include<sys/types.h>
  8. #include<linux/tcp.h>
  9.   #include<linux/udp.h>
  10. #include<linux/ip.h>
  11. #include<unistd.h>
  12. #include<signal.h>
  13. #include<pthread.h>
  14. #include<malloc.h>

  15. #define STREAMSIZE 10000
  16. #define BUFSIZE 2048
  17. #define CACHESIZE 20
  18. /*stream item info struct*/
  19. typedef struct {
  20.         unsigned short type;/*tcp or udp type */
  21.         unsigned int sport;
  22.         unsigned int dport;
  23.         unsigned int sip;
  24.         unsigned int dip;
  25.         unsigned long count;
  26.         unsigned long bytes;/*total bytes of a stream*/
  27. }stream;

  28. /*stream temp cache info struct*/
  29. typedef struct {
  30.         unsigned int type;
  31.         unsigned int weight;
  32.         unsigned int sport;
  33.         unsigned int dport;
  34.         unsigned int sip;
  35.         unsigned int dip;
  36. }cache_info;

  37. cache_info cache_item[CACHESIZE];     /*streams last captured to make a queue*/
  38. stream *item[STREAMSIZE];                 /*items are for stream info*/
  39. int capture=1;
  40. unsigned int item_max=0;                 /* current total items*/
  41. unsigned int proto,sip,dip,sport,dport,ip_h_len,n_read=0;

  42. void report()
  43. {
  44. int i=0,j;
  45. char pro_type[3];
  46. printf("    protocol\tsrc\t\tdest\t    sport  dport  packets\ttotal bytes\n");
  47. for(i=1;i<=item_max;i++)
  48. {
  49. printf("\t%d\t%s\t%s  %d   %d   %d\t\t%d\n",item[i]->type,inet_ntoa(item[i]->sip),inet_ntoa(item[i]->dip),ntohs(item[i]->sport),ntohs(item[i]->dport),item[i]->count,item[i]->bytes);
  50. }


  51. }
  52. void sig_handle(int signo)
  53. {
  54. capture=0;
  55. report();
  56. exit(1);
  57. }


  58. /*function for caching items that did not find in cache queue*/
  59. void insert_cache_item()
  60. {
  61. printf("insert cache_item");
  62. int i,id=11;
  63. for(i=0;i<CACHESIZE;i++)
  64. {
  65. id=(id < cache_item[i].weight)? id : (cache_item[i].weight);
  66. if(cache_item[i].weight==0)
  67. {
  68. cache_item[i].type=proto;
  69. printf(" %d\n",i);
  70. cache_item[i].sport=sport;
  71. cache_item[i].dport=dport;
  72. cache_item[i].sip=sip;
  73. cache_item[i].dip=dip;
  74. cache_item[i].weight+=2;
  75. break;
  76. }
  77. }
  78. if(id>0)                   /*in the cache_item,all weight is great than 0,but we
  79.                            find the smallest weight is id,so cache_item[id]will be
  80.                             recoverd by the new stream*/
  81. {
  82. printf(" %d\n",id);
  83. cache_item[id].type=proto;
  84. cache_item[id].sport=sport;
  85. cache_item[id].dport=dport;
  86. cache_item[id].sip=sip;
  87. cache_item[id].dip=dip;
  88. cache_item[id].weight=+1;
  89. }
  90. }

  91. /*search the stream current captured in our cache_item.
  92. the cache_item contains an item "weight" to record
  93. how offen this stream being captured recently.when capture
  94. a stream,first check it in cache_item,if find a match one,good,we
  95. need not to search the big item array which contains all
  96. stream items we captured before.

  97. the algorithm of the weight is sample,weight is bettween 0-10,
  98. when first insert into cache_item or the current captured stream
  99. has been in cache_item,we add 2 to the stream weight.and at the
  100. same time sub 1 to other stream item's weight.when the cache_item
  101. is full,the item which has the smallest weight will be coverd.and
  102. this is done by the insert_cache_item function*/

  103. int search_cache_item()
  104. {
  105. int i,j=-1;
  106. for(i=0;i<CACHESIZE;++i)
  107. {
  108. if(cache_item[i].type=proto&&cache_item[i].sport==sport&&cache_item[i].dport==dport&&cache_item[i].sip==sip&&cache_item[i].dip==dip)
  109. {
  110. if(cache_item[i].weight<=10)
  111. {
  112. cache_item[i].weight+=2;
  113. }
  114. j=i;
  115. }/*we hava find one that match the current stream*/
  116. else
  117. {
  118. if(cache_item[i].weight>=1)
  119. cache_item[i].weight-=1;
  120. }
  121. }
  122. printf("search_cache_item result is %d\n",j);
  123. return j;
  124. }
  125. /*function to search the stream current captured
  126. in the item[] which contains all the streams captured
  127. before.*/
  128. int search_item()
  129. {
  130. printf(" search in the item \n");
  131. int i=0,j;
  132. for(i=0;i<item_max;i++)
  133. {
  134. if(item[i]->sip==sip&&item[i]->sport==sport&&item[i]->dport==dport&&item[i]->type==proto&&item[i]->dip==dip)
  135. {
  136. item[i]->count+=1;
  137. item[i]->bytes+=n_read;
  138. break;
  139. }
  140. }
  141. j=(i<item_max)? 1:-1;
  142. printf("search in the item result is %d\n",j);
  143. return j;
  144. }
  145. /*function to add the current stream captured to
  146. the stream struct list*/
  147. int add_to_item()
  148. {
  149. if(item_max<STREAMSIZE)
  150. {
  151. printf("item_max is %d\n",item_max);
  152. item[item_max]=(stream *)(malloc(sizeof(stream)));
  153. memset(item[item_max],0,sizeof(stream));
  154. item[item_max]->type=proto;
  155. item[item_max]->sip=sip;
  156. item[item_max]->dip=dip;
  157. item[item_max]->sport=sport;
  158. item[item_max]->dport=dport;
  159. item[item_max]->bytes+=n_read;
  160. item[item_max]->count=+1;
  161. item_max=item_max+1;
  162. }
  163. else
  164. {
  165. fprintf(stderr,"stream is to large please change the STREAMSIZE\n");
  166. exit(1);
  167. }
  168. }

  169. void main(int argc,char *argv[])
  170. {
  171. int i,ret,id,sockfd;
  172. char buf[BUFSIZE];
  173. struct tcphdr *tcp_head;
  174. struct udphdr *udp_head;
  175. struct iphdr *ip_head;
  176. char *p;

  177. for(i=0;i<CACHESIZE;i++)
  178. {
  179. cache_item[i].weight=0;
  180. }
  181. signal(SIGINT,sig_handle);
  182. if((sockfd = socket(PF_PACKET,SOCK_RAW,htons(ETH_P_IP)))<0)
  183. {
  184.         fprintf(stderr,"socket error\n");
  185.         printf("%d","sockfd");
  186.         exit(1);
  187. }

  188. while(capture)
  189. {
  190. n_read = recvfrom(sockfd,buf,BUFSIZE,0,NULL,NULL);
  191. ip_head = (struct iphdr *)(buf+14);
  192. /*14=6 source mac address
  193.      6 destnation mac address
  194.      2 type
  195. */
  196. proto=ip_head->protocol;
  197. sip=ip_head->saddr;
  198. dip=ip_head->daddr;
  199. ip_h_len=ip_head->ihl<<2;
  200. if(proto==IPPROTO_TCP)
  201. {
  202. tcp_head = (struct tcphdr *)(buf+14+ip_h_len);
  203. sport=tcp_head->source;
  204. dport=tcp_head->dest;
  205. if((id=search_cache_item())>=0)/*current stream is in cache*/
  206. {
  207. item[id]->count+=1;
  208. item[id]->bytes+=n_read;
  209. printf("use cache info\n");
  210. }
  211. else
  212. {
  213. insert_cache_item(); /*cache it */
  214. if((ret=search_item())<0)
  215. {
  216. add_to_item();
  217. }
  218. }
  219. }
  220. else if(proto==IPPROTO_UDP)
  221. {
  222. udp_head=(struct udphdr *)(buf+14+ip_h_len);
  223. sport=udp_head->source;
  224. dport=udp_head->dest;
  225. if(id=search_cache_item()>0)
  226. {
  227. item[id]->count+=1;
  228. item[id]->bytes+=n_read;
  229. }
  230. else
  231. {
  232. insert_cache_item();
  233. if(search_item()<0)
  234. add_to_item();
  235. }
  236. }
  237. }
  238. }
复制代码

作者: heut2009    时间: 2010-12-03 16:44
环境 redhat 5 gcc 4.1.1
作者: yan8790511    时间: 2010-12-03 23:53
mark{:3_183:}
作者: surpass_li    时间: 2010-12-04 22:15
回复 78# renxiao2003


    和你没法比,呵呵
作者: renxiao2003    时间: 2010-12-04 23:20
回复 83# surpass_li


    慢慢比吧。
作者: zhanglistar    时间: 2010-12-05 20:29
回复 1# send_linux


    www.baidu.com   
     那个内部地址也能打印出来???
作者: xiaozhenggang    时间: 2010-12-06 12:28

作者: hanxuaiztt    时间: 2010-12-06 13:02
已经超出我的理解范围
作者: redhatuser    时间: 2010-12-06 14:27
瞎点了一下就跑这里来了,,,支持一下
作者: zhanglistar    时间: 2010-12-06 14:34
二四题的难度太高了。都没找到参考资料。难哦。
renxiao2003 发表于 2010-12-03 09:38


可以使用libpcap的库不???
作者: renxiao2003    时间: 2010-12-06 14:47
回复 89# zhanglistar


    不知道。问问楼主。我用那个写了一下没明白。
作者: zhanglistar    时间: 2010-12-06 15:02
回复 90# renxiao2003

google了下,使用PF_PACKET可以抓包,实现sniffer的功能。
作者: renxiao2003    时间: 2010-12-06 16:10
回复 91# zhanglistar


    2和4太难。不做了。呵呵。
作者: zhanglistar    时间: 2010-12-06 20:43
回复  zhanglistar


    2和4太难。不做了。呵呵。
renxiao2003 发表于 2010-12-06 16:10



    第二题实现不难啊,关键是要效率和精准。我觉得可以用多进程可能会好点。   
    第四题还没仔细看。   题目好长
作者: zhanglistar    时间: 2010-12-06 20:59
回复  zhanglistar


    2和4太难。不做了。呵呵。
renxiao2003 发表于 2010-12-06 16:10



    第三道题目的多核特性是怎么用的呢?     想请教兄台这方面的东西,想用归并排序。
作者: renxiao2003    时间: 2010-12-06 21:40
我没用多核特性(根本不会),只是用了普通的方法实现。
作者: renxiao2003    时间: 2010-12-06 21:40
第四题像要实现一个简单的关系数据库。难。
作者: renxiao2003    时间: 2010-12-08 09:41
大家做得都怎么样了。有人说第二题不难。主要是对网络也不熟悉(当然C和C++也是不熟悉)。所以做起来就比较难啊。
作者: heut2009    时间: 2010-12-08 13:12
回复 97# renxiao2003


    第二题,写了个简单的,但是有bug啊,你给看看
http://bbs.chinaunix.net/thread-1820953-8-1.html
作者: renxiao2003    时间: 2010-12-08 13:21
回复 98# heut2009


    哥们,我的C就是菜鸟都不是的角色。呵呵。
作者: zhanglistar    时间: 2010-12-08 20:26
第四题像要实现一个简单的关系数据库。难。
renxiao2003 发表于 2010-12-06 21:40



    有什么思路没????
    mysql是用C实现的吧?




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2