Chinaunix首页 | 论坛 | 博客
  • 博客访问: 472837
  • 博文数量: 120
  • 博客积分: 1853
  • 博客等级: 上尉
  • 技术积分: 1177
  • 用 户 组: 普通用户
  • 注册时间: 2011-10-22 22:40
文章分类

全部博文(120)

文章存档

2013年(16)

2012年(104)

分类:

2012-08-10 17:09:23

    借鉴了《unix网络编程API》上面的关于traceroute的命令,目的是进一步理解sock_raw,本程序只适用于ipv4。
    从这次编程中,学到了:
    (1)注意=和== 的区别,对于有判断的还好点,有时候能直接看到,但是如果只是一个句子(如done=1和done==1),这和时候就不好找了,坑了我好几次啊。
    (2)alarm(0)是用来取消原来的闹铃的
    (3)《unix网络编程API》关于超时的设置是错的,因为signal(SIGALRM, sigz_alrm)中的signal函数,会自动重启(我用的ubuntu12.04,因为sigaction中的ai_flags选项中只有SA_RESTART), 即由于信号处理而中断的函数重新运行,而不会中断产生errno=EINT;
    (4) socket选项中的SOCK_RAW必须是超级用户才能运行。
    (5) 可以通过setsockopt(sendfd, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl)可以设置ttl
    (6) 用sendfd(用于SOCK_DGRAM)来发送,用recvfd(用于SOCK_RAW, IPPROTO_ICMP)来接收,即收发可以是不同的描述符
     (7)  strncpy,strncmp与memcpy, memcmp是不同的,因为前者的实现是对“字符串”而言的,如果没有遇到\0,且没有到达最后,其中某一个大于另一个则返回,换句话说, 如果遇到了\0,就回直接出现结果,因此,不适合比较结构体(结构体中可能有\0,比较就会终止,而我要比较的是两个结构体的每一个字节),而memcpy则只是比较字节的大小,不管是否是字符串,是否结束,因此可以比较结构体;strncpy与memcpy也有类似的\0的问题。
    (8)bind函数,如果地址没有给出,只给出了端口号,则内核会自动分配地址的。
    (9)一些socket函数:
         inet_ntop    : 已知地址,想返回字符串表示
         inet_pton    : 已知字符串表示,想返回二进制地址
         htons/ntohs  : 端口号(或者两字节的什么东东), uint16_t
         htonl/ntohl  : 地址(或者四字节的什么东东),  uint32_t
         getaddrinfo  : 已知要获取的主机的信息的ip(ipv4,ipv6均可)地址或者主机名字或者服务端口                         号,返回关于主机的信息,包括ip地址,主机名(ai_canonname),地址长度,协                         议,端口号,family等
    (10) gettimeofday(struct timeval *tv, struct timezone *tz)微妙级别的运算,如本程序中的ms的运算就是通过此函数获得的。
    (11) 最坑爹的是recvfrom函数(ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,struct sockaddr *src_addr, socklen_t *addrlen)),如果过用sock_raw,其最后一个参数是长度。当把长度设置成小于16(ipv4的struct sockaddr_in的长度)时,src_addr得到的是全是0,而利用buf可以得到对方的地址,但是当长度大于16时,可以得到正确的地址(不是0了)------虽然因为addrlen参数是值-结果类型的参数,最后的结果都是16.

源代码附件: tracerout.zip   
           直接make就行了。
阅读(2176) | 评论(0) | 转发(0) |
0

上一篇:ping命令

下一篇:ping命令

给主人留下些什么吧!~~