【工具】ubuntu16安装sendip发包工具,模拟发送tcp/udp/icmp报文_ubantu上安装sendip-程序员宅基地

技术标签: ubuntu  linux  

写在开篇,最近因为测试需求,要使用Linux虚机模拟tcp/udp等协议报文,网上一搜,工具很多,文档不少,看着也不难,结果一装一堆报错,令人头秃。。。

最后翻到这篇文章真的是太绝了,瞬间解决安装报错问题,也才发现原来其实并不需要下载安装包再解压之类的操作就可以实现安装使用。。。

原文链接:https://blog.csdn.net/hgz_gs/article/details/89848536 (注:本文就实际操作中遇到的小细节出现的问题做了略微修改,比如使用apt-get进行安装时需要先update更新)

 

1、发包工具

1.1 sendip

1.2 tcpreply

2、抓包工具

2.1、tcpdump

2.2 tcpflow

3、速率测试工具

4、加密工具

4.1 tcpcryptd

5.linux网络编程

5.1、tcp

5.2、udp


1、发包工具

1.1 sendip

Sendip是一个linux平台的命令行发数据包工具,目前(2018年2月)支持的协议有ipv4、ipv6、icmp、tcp、udp、bgp、rip、ntp。

安装:

sudo apt-get update

sudo apt-get install sendip

源码下载地址:

https://github.com/rickettm/SendIP

 简单使用:

(举例:

1、发送ICMPv4报文,-p icmp 将默认发送ICMP echo request报文,-v选项可在终端打印发送的报文

sendip -v -p ipv4 -is 192.168.2.129 -id 192.168.2.1 -p icmp -d 0xcafecafecafe 192.168.2.1

-v:打印发送报文内容

-p:协议(支持ipv4/ipv6/icmp/tcp/udp/...)

-is:源ip

-id:目的Ip

-d:携带的内容

 

2、发送TCP报文

sendip -v -p ipv4 -is 20.1.1.20 -id 20.1.1.21 -p tcp -ts 1024 -td 1024 -d 0xcafecafecafeabcdef 20.1.1.21

-ts:源端口

-td:目的端口

在目的端抓包查看该报文:tcpdump host 20.1.1.20 -nei ens160

05:28:54.673093 00:50:56:a6:79:73 > 00:50:56:a6:40:3e, ethertype 802.1Q (0x8100), length 64: vlan 520, p 0, ethertype IPv4, 20.1.1.20.200 > 20.1.1.21.300: Flags [S], seq 2250301441:2250301447, win 65535, length 6

 

 

3、发送IPv4 UDP报文,发送TCP只需把udp替换为tcp即可

sendip -v -p ipv4 -is 20.1.1.20 -id 20.1.1.21 -p udp -us 200 -ud 300 -d 0xcafecafecafe 20.1.1.21

 

抓包:

05:32:30.514950 00:50:56:a6:79:73 > 00:50:56:a6:40:3e, ethertype 802.1Q (0x8100), length 64: vlan 520, p 0, ethertype IPv4, 20.1.1.20.200 > 20.1.1.21.300: UDP, length 6

 

4、发送IPv6 UDP报文,同样发送TCP仅需把udp替换为tcp

sendip -p ipv6 -6s 2::3 -p udp -d 0xcafe 2::1

 

通用选项:

 
  1. -d 要携带的数据。rN随机产生N个字节,0x之后带十六进制,0之后带8进制。

  2. -f 从文件中读取要携带的数据。

  3. -p 加载协议模块,只有加载了才能使用。

  4. -v 打印整个发出的包。

ipv4模块:

 
  1. -iv x 版本 Default: 4

  2. -ih x 首部长度 Default: Correct

  3. -iy x 区分服务 Default: 0

  4. -il x 总长度 Default: Correct

  5. ----------------------------------------------32bit

  6. -ii x 标识 Default: Random

  7. -ifr x 标志 Default: 0 (options are 0,1,r)

  8. -if x 片偏移 Default: 0

  9. ----------------------------------------------32bit

  10. -it x 生存时间 Default: 255

  11. -ip x 协议 Default: 0, or set by underlying protocol

  12. -ic x 首部检验和 Default: Correct

  13. ----------------------------------------------32bit

  14. -is x 源地址 Default: 127.0.0.1

  15. ----------------------------------------------32bit

  16. -id x 目的地址 Default: Correct

  17. ----------------------------------------------32bit

  18. 下面全是可选字段(比较少用,不译):

  19.  
  20. -ifd x IP don't fragment flag (see README)

  21. Default: 0 (options are 0,1,r)

  22. -ifm x IP more fragments flag (see README)

  23. Default: 0 (options are 0,1,r)

  24. -ionum x

  25. IP option as string of hex bytes (length is always correct)

  26. Default: (no options)

  27. -ioeol IP option: end of list

  28. -ionop IP option: no-op

  29. -iorr x

  30. IP option: record route. Format: pointer:addr1:addr2:...

  31. -iots x

  32. IP option: timestamp. Format: pointer:overflow:flag:(ip1:)ts1:(ip2:)ts2:...

  33. -iolsr x

  34. IP option: loose source route. Format: pointer:addr1:addr2:...

  35. -iosid x

  36. IP option: stream identifier

  37. -iossr x

  38. IP option: strict source route. Format: pointer:addr1:addr2:...

tcp模块:

 
  1. -ts x 源端口 Default: 0

  2. -td x 目的端口 Default: 0

  3. ----------------------------------------------32bit

  4. -tn x 序号 Default: Random

  5. ----------------------------------------------32bit

  6. -ta x 确认号 Default: 0

  7. ----------------------------------------------32bit

  8. -tt x 数据偏移 Default: Correct

  9. -tr x 保留(ECN、CWR看rfc2481) Default: 0

  10. -tfu x URG Default: 0, or 1 if -tu specified (options are 0,1,r)

  11. -tfa x ACK Default: 0, or 1 if -ta specified (options are 0,1,r)

  12. -tfp x PSH Default: 0 (options are 0,1,r)

  13. -tfr x RST Default: 0 (options are 0,1,r)

  14. -tfs x SYN Default: 1 (options are 0,1,r)

  15. -tff x FIN Default: 0 (options are 0,1,r)

  16. -tw x 窗口 Default: 65535

  17. ----------------------------------------------32bit

  18. -tc x 检验和 Default: Correct

  19. -tu x 紧急指针 Default: 0

  20. ----------------------------------------------32bit

  21. 下面全是可选字段(比较少用,不译):

  22. -tonum x TCP option as string of hex bytes (length is always correct)

  23. Default: (no options)

  24. -toeol TCP option: end of list

  25. -tonop TCP option: no op

  26. -tomss x

  27. TCP option: maximum segment size

  28. -towscale x

  29. TCP option: window scale (rfc1323)

  30. -tosackok

  31. TCP option: allow selective ack (rfc2018)

  32. -tosack x

  33. TCP option: selective ack (rfc2018), format is l_edge1:r_edge1,l_edge2:r_edge2...

  34. -tots x

  35. TCP option: timestamp (rfc1323), format is tsval:tsecr

udp模块:

 
  1. -us x 源端口 Default: 0

  2. -ud x 目的端口 Default: 0

  3. -ul x 长度 Default: Correct

  4. -uc x 检验和 Default: Correct

要注意,按照从左到右的顺序依次封装报文,所以ip报文必须写在其他报文之前。如果协议中需要检验和之类的就按默认的就行了,省去计算的痛苦。下面有几个例子:

1、发送ICMPv4报文,-p icmp 将默认发送ICMP echo request报文,-v选项可在终端打印发送的报文

sendip -v -p ipv4 -is 192.168.2.129 -id 192.168.2.1 -p icmp -d 0xcafecafecafe 192.168.2.1


2、发送ICMPv6报文

sendip -p ipv6 -6s 2::3 -p icmp -d 0xcafecafecafe 2::1


3、发送IPv4 UDP报文,发送TCP只需把udp替换为tcp即可

sendip -p ipv4 -is 192.168.2.129 -p udp -d 0xcafe 192.168.2.1


4、发送IPv6 UDP报文,同样发送TCP仅需把udp替换为tcp

sendip -p ipv6 -6s 2::3 -p udp -d 0xcafe 2::1

5、将 test文件内容发送到udp端口

sendip -v -p ipv4 -id 14.215.177.39 -p udp -f test www.baidu.com

sendip -p ipv4 -is 192.168.1.2 -id 192.168.1.1 -p icmp -d 0x89ABCDEF www.google.com
 

其中主要的结构是sendip 网络层 上一层 数据 domain,domain是目的主机,可以是www.baidu.com192.168.1.1之类的。如果出现什么错误就会打印出帮助信息,里面有一行是提示错误原因,别漏看了。至于能不能发不规则的包(如数据与报文长度不符合、校验和乱写之类的),实际会不会发出去就没进行测试了。

1.2 tcpreply

tcpreplay是一种pcap包的重放工具, 它可以将用ethreal, wireshark工具抓下来的包原样或经过任意修改后重放回去. 它允许你对报文做任意的修改(主要是指对2层, 3层, 4层报文头), 指定重放报文的速度等, 这样tcpreplay就可以用来复现抓包的情景以定位bug, 以极快的速度重放从而实现压力测试。

安装使用方法参考:

https://blog.csdn.net/zhaomax/article/details/82773381

2、抓包工具

2.1、tcpdump

tcpdump :tcpdump可以将网络中传送的数据包完全截获下来提供分析。它支持针对网络层、协议、主机、网络或端口的过滤,并提供and、or、not等逻辑语句来帮助你去掉无用的信息。

ubuntu安装方法:

sudo apt-get install tcpdump

源码下载地址:

http://www.tcpdump.org/

嵌入式移植参考方法:

https://www.cnblogs.com/baiduboy/p/6243450.html

 使用语法:

在Linux操作系统中,必须使用系统管理员权限方能执行。

tcpdump [-adeflnNOpqStvx][-c<数据包数目>][-dd][-ddd][-F<表达文件>][-i<网络界面>][-r<数据包文件>][-s<数据包大小>][-tt][-T<数据包类型>][-vv][-w<数据包文件>][输出数据栏位]

参数说明

  • -a 尝试将网络和广播地址转换成名称。
  • -c<数据包数目> 收到指定的数据包数目后,就停止进行倾倒操作。
  • -d 把编译过的数据包编码转换成可阅读的格式,并倾倒到标准输出。
  • -dd 把编译过的数据包编码转换成C语言的格式,并倾倒到标准输出。
  • -ddd 把编译过的数据包编码转换成十进制数字的格式,并倾倒到标准输出。
  • -e 在每列倾倒资料上显示连接层级的文件头。
  • -f 用数字显示网际网络地址。
  • -F<表达文件> 指定内含表达方式的文件。
  • -i<网络界面> 使用指定的网络截面送出数据包。
  • -l 使用标准输出列的缓冲区。
  • -n 不把主机的网络地址转换成名字。
  • -N 不列出域名。
  • -O 不将数据包编码最佳化。
  • -p 不让网络界面进入混杂模式。
  • -q 快速输出,仅列出少数的传输协议信息。
  • -r<数据包文件> 从指定的文件读取数据包数据。
  • -s<数据包大小> 设置每个数据包的大小。
  • -S 用绝对而非相对数值列出TCP关联数。
  • -t 在每列倾倒资料上不显示时间戳记。
  • -tt 在每列倾倒资料上显示未经格式化的时间戳记。
  • -T<数据包类型> 强制将表达方式所指定的数据包转译成设置的数据包类型。
  • -v 详细显示指令执行过程。
  • -vv 更详细显示指令执行过程。
  • -x 用十六进制字码列出数据包资料。
  • -w<数据包文件> 把数据包数据写入指定的文件。

使用例子:

1. tcpdump -D 获取网络适配器列表,以下是在Ubuntu上获取到的结果:

hegaozhi@ubuntu:~$ tcpdump -D
1.ens33 [Up, Running]
2.any (Pseudo-device that captures on all interfaces) [Up, Running]
3.lo [Up, Running, Loopback]
4.bluetooth0 (Bluetooth adapter number 0)
5.nflog (Linux netfilter log (NFLOG) interface)
6.nfqueue (Linux netfilter queue (NFQUEUE) interface)
7.usbmon1 (USB bus number 1)
8.usbmon2 (USB bus number 2)
9.usbmon3 (USB bus number 3)
10.usbmon4 (USB bus number 4)

2. tcpdump -i <需要监控的网络适配器编号>,例如监控网卡ens33 ,则使用tcpdump -i 1。 

hegaozhi@ubuntu:~$ sudo tcpdump -i 1
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ens33, link-type EN10MB (Ethernet), capture size 262144 bytes

3. 使用无线网卡ens33 监控IP地址为172.16.86.111上443端口的tcp协议:

sudo tcpdump -i 1 host 172.16.86.111 and tcp port 443

4. 使用无线网卡ens33 监控IP地址为172.16.86.111上8308端口的udp协议:

sudo tcpdump -i 1 host 172.16.86.111 and udp port 8308

5. 如果想要显示数据包的内容,需要使用-X参数,如,我想要显示捕获的https数据包http header的内容:

sudo tcpdump -X -i 1 host 172.16.86.111 and tcp port 443

    可以看到该结果只显示了https头的一部分,没有显示全,是因为tcpdump默认将显示的数据长度截断了,可以使用-s后面加数据长度,来设置数据显示长度:

sudo tcpdump -X -s 0 -i 1 host 172.16.86.111 and tcp port 443

以上的例子中,-s 0 表示自动设置长度使其能够显示所有数据。

  6. 使用-w参数将捕获的数据存储为.cap文件:

sudo tcpdump -X -s 0 -i 1 -w tcplog.cap host 192.9.200.59 and tcp port 8000

使用-r参数查看.cap 文件:

sudo tcpdump -X -s 0 -i 1 -r tcplog.cap host 172.16.86.111 and tcp port 443

7. 抓192.168.1.123的80端口和110和25以外的其他端口的包 

sudo tcpdump -i eth1 host 192.168.1.123 and ! port 80 and ! port 25 and ! port 110 -w /tmp/xxx.cap

8.抓pppoe的密码 

sudo tcpdump -i eth1 pppoes -w /tmp/xxx.cap

9.后台抓包, 控制台退出也不会影响: 

sudo  nohup tcpdump -i eth1 port 110 -w /tmp/xxx.cap & 

10.以100m大小分割保存文件, 超过100m另开一个文件 -C 100m 

sudo tcpdump -i eth1 pppoes -w /tmp/xxx.cap -C 100m 

11.抓10000个包后退出 -c 10000 

sudo tcpdump -i eth1 pppoes -w /tmp/xxx.cap -c 10000 

 

抓下来的.cap文件可以直接用ethereal 或者wireshark打开。

2.2 tcpflow

tcpflow实际上也是一个抓包工具,tcpflow与tcpdump不同的是它是以流为单位显示数据内容,而tcpdump以包为单位显示数据。分析HTTP数据,使用tcpflow会更便捷。

#截取本机(192.168.31.147)和主机114.114.114.114之间的数据
tcpdump -n -i eth0 host 192.168.31.147 and 114.114.114.114
#截取全部进入服务器的数据可以使用以下的格式
tcpdump -n -i eth0 dst 192.168.31.147
#服务器有多个IP 可以使用参数
tcpdump -n -i eth0 dst 192.168.31.147  or  192.168.31.157
#从本机出去的数据包
tcpdump -n -i eth0 src 192.168.31.147 or 192.168.31.157

-C:在将一个原始数据包写入一个保存文件之前,请检查该文件是否大于 file_size ,如果是,关闭当前的保存文件并打开一个新文件。第一个保存文件后的保存文件将具有用-w 标志指定的名称 ,后面跟着一个数字,从1开始并继续向上。file_size的单位 是数百万字节(1,000,000字节,而不是1,048,576字节)。

-w:将原始数据包写入 文件, 而不是解析并打印出来。他们以后可以用-r选项打印。如果文件 是“ - ”,则使用标准输出。

-W:与-C 选项一起使用时 ,这会将创建的文件数量限制为指定的数字,并从头开始覆盖文件,从而创建“旋转”缓冲区。另外,它将命名带有足够前导0的文件来支持最大数量的文件,使它们能够正确排序。与-G 选项一起使用时 ,这将限制创建的旋转转储文件的数量,在达到限制时以状态0退出。如果与-C一起使用 ,则行为将导致每个时间片的循环文件

 

3、速率测试工具

  ping命令是一条最基础的测试本机到目的ip连通性的工具,如下图,不带任何参数的ping命令默认每秒发送一个数据包,并返回结果,按下CTRL+C结束,而如果使用-f参数则可以快速不断发送icmp数据包,可以通过-f参数查看大概的丢包率 ping命令返回结果中可以看到总共发送了多少个包,有多少个包被成功接收,丢包率是多少,ping的总共时长是多少等等

Linux几个常用网络诊断工具总结

Linux下ping大数据包的格式;

语  法:ping [-aAbBdDfhLnOqrRUvV] [-I 本地网卡名或者IP地址] [-c<完成次数>][-i<间隔秒数>][-l<指定数量的信息包>][-p<设置icmp报文数据的内容>][-s<数据包大小单位字节(B),>][-t<存活数值>] [-w 指定等待的超时时间] [-W 超时时间]  [主机名称或IP地址]

 

4、加密工具

4.1 tcpcryptd

5.linux网络编程

5.1、tcp

服务器server.c代码:

 
  1. #include<stdio.h>

  2. #include<stdlib.h>

  3. #include<string.h>

  4. #include<errno.h>

  5. #include<sys/types.h>

  6. #include<sys/socket.h>

  7. #include<netinet/in.h>

  8. #include<termios.h>

  9. #include<sys/types.h>

  10. #include<sys/stat.h>

  11. #include<fcntl.h>

  12. #include<unistd.h>

  13. #include<sys/ioctl.h>

  14. #include<signal.h>

  15.  
  16. #define MAXLINE 256

  17. #define PORT 6666

  18. int listenfd;

  19. int connfd;

  20. pthread_t read_id, write_id;

  21.  
  22. /*

  23. linux ctrl + C 会产生 SIGINT信号

  24. 接收到SIGINT 信号进入该函数

  25. */

  26. void stop(int signo)

  27. {

  28. printf("stop\n");

  29. close(connfd);

  30. close(listenfd);

  31. _exit(0);

  32. }

  33.  
  34. /*

  35. 当客户端断开连接的时候,

  36. 在服务端socket send进程可以收到收到信号SIGPIPE,

  37. 收到SIGPIPE信号进入该函数结束创建的线程。

  38. */

  39. void signal_pipe(int signo)

  40. {

  41. pthread_kill(read_id,SIGQUIT);//向read线程发送SIGQUIT

  42. pthread_join(read_id,NULL); //阻塞线程运行,直到read 线程退出。

  43.  
  44. close(connfd); //关闭连接

  45. printf("read pthread out \n");

  46.  
  47. pthread_exit(0); //结束write 线程

  48. }

  49.  
  50. /*

  51. read 线程接收到SIGQUIT信号,

  52. 执行线程退出操作

  53. */

  54. void pthread_out(int signo)

  55. {

  56. pthread_exit(0);

  57. }

  58.  
  59. /*

  60. read 线程执行函数

  61. */

  62. void* read_func(void* arg)

  63. {

  64. char readbuff[MAXLINE];

  65. int n = 0;

  66. int fd;

  67.  
  68. fd = *(int*)arg; /*main 主进程传递过来的连接文件描述符*/

  69. memset(&readbuff,0,sizeof(readbuff));

  70.  
  71. signal(SIGQUIT,pthread_out); /* 注册SIGQUIT 信号*/

  72. while(1)

  73. {

  74. n = recv(fd, readbuff, MAXLINE, 0); /*recv 在这里是阻塞运行*/

  75. if(n > 0)

  76. {

  77. printf("server recv data: %s \n",readbuff);

  78. }

  79. };

  80. }

  81. /*

  82. write 线程执行函数

  83. */

  84. void* write_func(void* arg)

  85. {

  86. char writebuff[MAXLINE];

  87. char* write = "I am server";

  88. unsigned char i = 0;

  89. int num = 0;

  90. int fd;

  91.  
  92. fd = *(int*)arg;

  93. memset(&writebuff,0,sizeof(writebuff));

  94.  
  95. signal(SIGPIPE,signal_pipe); /* 注册 SIGPIPE信号 */

  96. while(1)

  97. {

  98. sleep(1);

  99. send(fd,write,strlen(write)+1,0);/*向客户端发送数据*/

  100. }

  101. }

  102.  
  103. int main(int argc, char** argv)

  104. {

  105. char buff[MAXLINE];

  106. int num;

  107. int addrlen;

  108. struct sockaddr_in server_addr; /*服务器地址结构*/

  109. struct sockaddr_in client_addr; /*客户端地址结构*/

  110.  
  111. if((listenfd = socket(AF_INET,SOCK_STREAM,0)) == -1)/*建立一个流式套接字*/

  112. {

  113. printf("create socket error: %s(errno: %d)\n",strerror(errno),errno);

  114. exit(0);

  115. }

  116.  
  117. /*设置服务端地址*/

  118. addrlen = sizeof(struct sockaddr_in);

  119. memset(&server_addr, 0, addrlen);

  120. server_addr.sin_family = AF_INET; /*AF_INET表示 IPv4 Intern 协议*/

  121. server_addr.sin_addr.s_addr = htonl(INADDR_ANY); /*INADDR_ANY 可以监听任意IP */

  122. server_addr.sin_port = htons(PORT); /*设置端口*/

  123.  
  124. /*绑定地址结构到套接字描述符*/

  125. if( bind(listenfd, (struct sockaddr*)&server_addr, sizeof(server_addr)) == -1)

  126. {

  127. printf("bind socket error: %s(errno: %d)\n",strerror(errno),errno);

  128. exit(0);

  129. }

  130.  
  131. /*设置监听队列,这里设置为1,表示只能同时处理一个客户端的连接*/

  132. if( listen(listenfd, 1) == -1)

  133. {

  134. printf("listen socket error: %s(errno: %d)\n",strerror(errno),errno);

  135. exit(0);

  136. }

  137.  
  138. signal(SIGINT,stop); /*注册SIGINT 信号*/

  139. while(1)

  140. {

  141. printf("wait client accpt \n");

  142. if( (connfd = accept(listenfd, (struct sockaddr*)&client_addr, &addrlen)) == -1)/*接收客户端的连接,这里会阻塞,直到有客户端连接*/

  143. {

  144. printf("accept socket error: %s(errno: %d)",strerror(errno),errno);

  145. continue;

  146. }

  147.  
  148. if(pthread_create(&read_id,NULL,read_func,&connfd))/*创建 read 线程*/

  149. {

  150. printf("pthread_create read_func err\n");

  151. }

  152.  
  153. if(pthread_create(&write_id,NULL,write_func,&connfd))/*创建 write 线程*/

  154. {

  155. printf("pthread_create write_func err\n");

  156. }

  157.  
  158. pthread_join(write_id,NULL); /*阻塞,直到write进程退出后才进行新的客户端连接*/

  159. printf("write pthread out \n");

  160. }

  161. }

客户端client.c代码:

 
  1. #include<stdio.h>

  2. #include<stdlib.h>

  3. #include<string.h>

  4. #include<errno.h>

  5. #include<sys/types.h>

  6. #include<sys/socket.h>

  7. #include<netinet/in.h>

  8. #include<termios.h>

  9. #include<sys/types.h>

  10. #include<sys/stat.h>

  11. #include<fcntl.h>

  12. #include<unistd.h>

  13. #include<sys/ioctl.h>

  14. #include<signal.h>

  15.  
  16. #define MAXLINE 256

  17. #define PORT 6666

  18. int fd;

  19. /*

  20. linux ctrl + C 会产生 SIGINT信号

  21. 接收到SIGINT 信号进入该函数

  22. */

  23. void stop(int signo)

  24. {

  25. printf("client stop\n");

  26. close(fd);

  27. _exit(0);

  28. }

  29.  
  30. /*客户端处理函数*/

  31. void client_process(void)

  32. {

  33. char readbuff[MAXLINE];

  34. char writebuff[MAXLINE];

  35. char * write = "I am client";

  36. int num = 0;

  37.  
  38. while(1)

  39. {

  40. num = recv(fd,readbuff,MAXLINE,0);/*接收服务端的数据,recv在这里如果没有数据会阻塞*/

  41. if(num > 0)

  42. {

  43. printf("client read data : %s \n",readbuff);

  44. send(fd, write, strlen(write)+1, 0); /*接收到数据后再向服务端发送一个字符串*/

  45. }

  46. else if(num == 0)/*recv返回值为0 的时候表示服务端已经断开了连接*/

  47. {

  48. stop(1); /*执行退出操作*/

  49. }

  50. }

  51. }

  52.  
  53. int main(int argc, char** argv)

  54. {

  55. struct sockaddr_in server_addr;

  56. struct sockaddr_in client_addr;

  57. int ret;

  58.  
  59. fd = socket(AF_INET,SOCK_STREAM,0);/*建立流式套接字*/

  60. if(fd < 0)

  61. {

  62. printf("clinet socket err \n");

  63. }

  64.  
  65. /*设置服务端地址*/

  66. memset(&server_addr,0,sizeof(server_addr));

  67. server_addr.sin_family = AF_INET; /*AF_INET表示 IPv4 Intern 协议*/

  68. server_addr.sin_addr.s_addr = htonl(INADDR_ANY);/*INADDR_ANY 可以监听任意IP */

  69. server_addr.sin_port = htons(PORT); /*设置端口*/

  70.  
  71. inet_pton(AF_INET,argv[1],&server_addr.sin_addr);/*将用户输入的字符串类型的IP地址转为整型*/

  72. connect(fd,(struct sockaddr*)&server_addr,sizeof(server_addr));/*连接服务器*/

  73.  
  74. signal(SIGINT,stop); /*注册SIGINT信号*/

  75. client_process(); /*进入处理函数*/

  76.  
  77. close(fd);/*关闭文件*/

  78. return 0;

  79. }

Makefile:

 
  1. CC = gcc

  2. CPP = g++

  3. RM = rm -rf

  4.  
  5. ## debug flag

  6. DBG_ENABLE = 1

  7.  
  8. ## source file path

  9. SRC_PATH := .

  10.  
  11. ## get all source files

  12. SRCS += $(wildcard $(SRC_PATH)/*.c)

  13.  
  14. ## target exec file name

  15. TARGET := $(SRCS:.c=)

  16.  
  17. ## all .o based on all .c

  18. OBJS := $(SRCS:.c=.o)

  19.  
  20.  
  21. ## need libs, add at here

  22. LIBS := pthread

  23.  
  24. ## used headers file path

  25. INCLUDE_PATH := .

  26.  
  27. ## used include librarys file path

  28. LIBRARY_PATH := /lib

  29.  
  30. ## debug for debug info, when use gdb to debug

  31. ifeq (1, ${DBG_ENABLE})

  32. CFLAGS += -D_DEBUG -O0 -g -DDEBUG=1

  33. endif

  34.  
  35. ## get all include path

  36. CFLAGS += $(foreach dir, $(INCLUDE_PATH), -I$(dir))

  37.  
  38. ## get all library path

  39. LDFLAGS += $(foreach lib, $(LIBRARY_PATH), -L$(lib))

  40.  
  41. ## get all librarys

  42. LDFLAGS += $(foreach lib, $(LIBS), -l$(lib))

  43.  
  44.  
  45. all: clean build $(TARGET)

  46.  
  47. build:

  48. gcc client.c -o client -lpthread

  49. gcc server.c -o server -lpthread

  50.  
  51. clean:

  52. $(RM) $(OBJS) $(TARGET)

 编译:

hegaozhi@ubuntu:~/tcp$ make

 运行:

先运行服务器:

./server

 新建终端运行客户端,其中127.0.0.1为服务器的ip地址:

./client 127.0.0.1

5.2、udp

客户端service.cpp代码:

 
  1. #include<stdio.h>

  2. #include<stdlib.h>

  3. #include<unistd.h>

  4. #include<errno.h>

  5. #include<sys/types.h>

  6. #include<sys/socket.h>

  7. #include<netinet/in.h>

  8. #include<string.h>

  9.  
  10. #define MYPORT 8308

  11.  
  12.  
  13. #define ERR_EXIT(m) \

  14. do { \

  15. perror(m); \

  16. exit(EXIT_FAILURE); \

  17. } while (0)

  18.  
  19. void echo_ser(int sock)

  20. {

  21. char recvbuf[1024] = {0};

  22. struct sockaddr_in peeraddr;

  23. socklen_t peerlen;

  24. int n;

  25.  
  26. while (1)

  27. {

  28.  
  29. peerlen = sizeof(peeraddr);

  30. memset(recvbuf, 0, sizeof(recvbuf));

  31. n = recvfrom(sock, recvbuf, sizeof(recvbuf), 0,

  32. (struct sockaddr *)&peeraddr, &peerlen);

  33. if (n <= 0)

  34. {

  35.  
  36. if (errno == EINTR)

  37. continue;

  38.  
  39. ERR_EXIT("recvfrom error");

  40. }

  41. else if(n > 0)

  42. {

  43. printf("接收到的数据:%s\n",recvbuf);

  44. sendto(sock, recvbuf, n, 0,

  45. (struct sockaddr *)&peeraddr, peerlen);

  46. printf("回送的数据:%s\n",recvbuf);

  47. }

  48. }

  49. close(sock);

  50. }

  51.  
  52. int main(void)

  53. {

  54. int sock;

  55. if ((sock = socket(PF_INET, SOCK_DGRAM, 0)) < 0)

  56. ERR_EXIT("socket error");

  57.  
  58. struct sockaddr_in servaddr;

  59. memset(&servaddr, 0, sizeof(servaddr));

  60. servaddr.sin_family = AF_INET;

  61. servaddr.sin_port = htons(MYPORT);

  62. servaddr.sin_addr.s_addr = htonl(INADDR_ANY);

  63.  
  64. printf("监听%d端口\n",MYPORT);

  65. if (bind(sock, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0)

  66. ERR_EXIT("bind error");

  67.  
  68. echo_ser(sock);

  69.  
  70. return 0;

  71. }

  72.  

客户端client.cpp代码:

 
  1. #include <unistd.h>

  2. #include <sys/types.h>

  3. #include <sys/socket.h>

  4. #include <netinet/in.h>

  5. #include <arpa/inet.h>

  6. #include <stdlib.h>

  7. #include <stdio.h>

  8. #include <errno.h>

  9. #include <string.h>

  10.  
  11. #define MYPORT 8308

  12. char* SERVERIP = "127.0.0.1";

  13.  
  14. #define ERR_EXIT(m) \

  15. do \

  16. { \

  17. perror(m); \

  18. exit(EXIT_FAILURE); \

  19. } while(0)

  20.  
  21. void echo_cli(int sock)

  22. {

  23. struct sockaddr_in servaddr;

  24. memset(&servaddr, 0, sizeof(servaddr));

  25. servaddr.sin_family = AF_INET;

  26. servaddr.sin_port = htons(MYPORT);

  27. //servaddr.sin_addr.s_addr = inet_addr(SERVERIP);

  28. servaddr.sin_addr.s_addr = htonl(INADDR_ANY);

  29.  
  30. int ret;

  31. char sendbuf[1024] = {0};

  32. char recvbuf[1024] = {0};

  33. while (fgets(sendbuf, sizeof(sendbuf), stdin) != NULL)

  34. {

  35.  
  36. printf("向服务器发送:%s\n",sendbuf);

  37. sendto(sock, sendbuf, strlen(sendbuf), 0, (struct sockaddr *)&servaddr, sizeof(servaddr));

  38.  
  39. ret = recvfrom(sock, recvbuf, sizeof(recvbuf), 0, NULL, NULL);

  40. if (ret == -1)

  41. {

  42. if (errno == EINTR)

  43. continue;

  44. ERR_EXIT("recvfrom");

  45. }

  46. printf("从服务器接收:%s\n",recvbuf);

  47.  
  48. memset(sendbuf, 0, sizeof(sendbuf));

  49. memset(recvbuf, 0, sizeof(recvbuf));

  50. }

  51.  
  52. close(sock);

  53.  
  54.  
  55. }

  56.  
  57. int main(void)

  58. {

  59. int sock;

  60. if ((sock = socket(PF_INET, SOCK_DGRAM, 0)) < 0)

  61. ERR_EXIT("socket");

  62.  
  63. echo_cli(sock);

  64.  
  65. return 0;

  66. }

  67.  

Makefile文件内容:

 
  1. CC = gcc

  2. CPP = g++

  3. RM = rm -rf

  4.  
  5. ## debug flag

  6. DBG_ENABLE = 1

  7.  
  8. ## source file path

  9. SRC_PATH := .

  10.  
  11. ## get all source files

  12. SRCS += $(wildcard $(SRC_PATH)/*.cpp)

  13.  
  14. ## target exec file name

  15. TARGET := $(SRCS:.cpp=)

  16.  
  17. ## all .o based on all .cpp

  18. OBJS := $(SRCS:.cpp=.o)

  19.  
  20.  
  21. ## need libs, add at here

  22. LIBS := pthread

  23.  
  24. ## used headers file path

  25. INCLUDE_PATH := .

  26.  
  27. ## used include librarys file path

  28. LIBRARY_PATH := /lib

  29.  
  30. ## debug for debug info, when use gdb to debug

  31. ifeq (1, ${DBG_ENABLE})

  32. CFLAGS += -D_DEBUG -O0 -g -DDEBUG=1

  33. endif

  34.  
  35. ## get all include path

  36. CFLAGS += $(foreach dir, $(INCLUDE_PATH), -I$(dir))

  37.  
  38. ## get all library path

  39. LDFLAGS += $(foreach lib, $(LIBRARY_PATH), -L$(lib))

  40.  
  41. ## get all librarys

  42. LDFLAGS += $(foreach lib, $(LIBS), -l$(lib))

  43.  
  44.  
  45. all: clean build $(TARGET)

  46.  
  47. build:

  48. g++ client.cpp -o client -lpthread

  49. g++ service.cpp -o service -lpthread

  50.  
  51. clean:

  52. $(RM) $(OBJS) $(TARGET)

运行:

先运行服务器:

hegaozhi@ubuntu:~/test/socket/udp$ ./service
监听2368端口
Velodyne socket fd is 3

新建终端运行客户端,并输入hello:

hegaozhi@ubuntu:~/test/socket/udp$ ./client
hello
向服务器发送:hello

6. 局域网在线IP探测

用nmap对局域网扫描一遍,然后查看arp缓存表就可以知道局域内ip对应的mac了。nmap比较强大也可以直接扫描mac地址和端口。执行扫描之后就可以 cat /proc/net/arp查看arp缓存表了。

             进行ping扫描,打印出对扫描做出响应的主机:  

$ nmap -sP 192.168.1.0/24  

仅列出指定网络上的每台主机,不发送任何报文到目标主机: 

$ nmap -sL 192.168.1.0/24 

探测目标主机开放的端口,可以指定一个以逗号分隔的端口列表(如-PS 22,23,25,80):  

$ nmap -PS 192.168.1.234  

使用UDP ping探测主机:

$ nmap -PU 192.168.1.0/24  

使用频率最高的扫描选项(SYN扫描,又称为半开放扫描),它不打开一个完全的TCP连接,执行得很快: 

$ nmap -sS 192.168.1.0/24

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_39068791/article/details/112605344

智能推荐

vscode c/c++ global插件实现代码跳转_c++ gnu global-程序员宅基地

文章浏览阅读1.1w次,点赞5次,收藏19次。在vscode阅读编写c/c++代码时,体验不是很好,有时候会无法跳转。这里通过GNU Global工具解决这个问题。_c++ gnu global

How to solve “Dynamic Web Module 3.1 requires Java 1.7 or newer” in Eclipse_dynamic web module 3.1 requires java 1.7 or newer -程序员宅基地

文章浏览阅读2.2k次。Have you noticed above type of error in yourEclipse? When you’re creating a project with Dynamic Web Module 3.1 support, you should be using Java 1.7 or newer. Please follow below steps to_dynamic web module 3.1 requires java 1.7 or newer in eclipse. how to solve i

Tomcat介绍-程序员宅基地

文章浏览阅读6.6w次,点赞43次,收藏427次。文章目录Tomcat介绍Container 结构分析Tomcat请求过程安装Tomcat优化tomcat启动速度Tomcat主要目录说明Tomcat 虚拟主机配置HTTP 请求过程Tomcat优化Tomcat介绍tomcat是一个免费的,开放源代码的Web应用服务器,是Apache软件基金会项目中的一个核心项目,由Apache ,Sun和一些公司以及个人共同开发而成,深受Java爱好者的喜爱,是一款比较流行的web应用服务器。Tomcat由一系列的组件构成,其中核心的组件有三个:(1) we_tomcat

内核函数前面单下划线和双下划线_linux内核函数 前置下划线-程序员宅基地

文章浏览阅读2.4k次。在我们阅读内核代码时,经常会看到有的函数名称前面会带有“_ _”的双下划线,而有些又没有,这个有什么用呢?原来内核API函数具有这种名称的,通常都是一些接口的底层函数,应该谨慎使用。实质上,这里的双下划线就是要告诉程序员:谨慎调用,后则后果自负。举个例子,在内核模块的初始函数时,实际的定义如下: static int _ _init initializition_funct_linux内核函数 前置下划线

[html] 如何更改浏览器左上角标题旁的图标?-程序员宅基地

文章浏览阅读1k次。[html] 如何更改浏览器左上角标题旁的图标?图标在html的head进行引入,如<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">个人简介我是歌谣,欢迎和大家一起交流前后端知识。放弃很容易,但坚持一定很酷。欢迎大家一起讨论主目录与歌谣一起通关前端面试题...

常见的 JVM 参数有哪些?_jvm参数未实名有+ 有--程序员宅基地

文章浏览阅读204次。参数格式:参数格式为:-XX:+参数 或者 -XX:-参数" + " 表示开启," - " 表示关闭,常用的 Boolean 类型参数有:1. 堆参数2. 回收器参数_jvm参数未实名有+ 有-

随便推点

python 使用API并将获取到的数据可视化的基本方法(详细)_根据api展示数据-程序员宅基地

文章浏览阅读2.8k次,点赞2次,收藏20次。我们将编写一个程序,它将会自动下载GitHub网站上星星最多的python项目的信息,并对这些信息简单可视化。_根据api展示数据

(转)em重建全过程-程序员宅基地

文章浏览阅读92次。该问题遇到N次,被郁闷N次,特此记录以备不时之需由于n久不用em,而本机在公司使用dhcp自动获取ip,导致ip变化,而使em启动报出ora-12514 DBD ERROR: OCIServerAttach的错误不得不禁用dhcp,分配固定ip并重建em,过程如下:1.删除EMC:\Documents and Settings\User&gt;emca -deconfig dbco..._重建em

SVN-git-github-版本控制服务器-程序员宅基地

文章浏览阅读3.5k次。一、 简述SVN版本控制服务SVN是Subversion的简称,是一个开放源代码的版本控制系统,相较于CVS,它采用了分支管理系统,它的设计目标就是取代CVS。互联网上很多版本控制服务已从CVS迁移到Subversion,也就是CVS的接班人!CVS是一个C/S系统,是一个常用的代码版本控制软件。主要在开源软件管理中使用。与它相类似的代码版本控制软件有subversion。多个开发人员通过一个..._svn-git

软件模拟spi接口 ,四种模式全支持_软件模拟spi需要分模式-程序员宅基地

文章浏览阅读1.2k次。1.0 .h需要定义的文件#define SET_GPIO(A) NRF_GPIO->OUTSET = (1UL << (A)) #define CLEAR_GPIO(A) NRF_GPIO->OUTCLR = (1UL << (A))#define READ_GPIO(A) NRF_GPIO->IN&(1<<(A))#..._软件模拟spi需要分模式

layui 获取select option 自定义属性_lay-options 获取-程序员宅基地

文章浏览阅读338次。最近在使用layui开发项目后台, 遇见这个问题, 记录一下, 方便自己和大家查看需要根据类型 展示不同表单内容_lay-options 获取

ZigBee 3.0 EmberZNet EFR32MG 学习笔记-9-Network Steering加网流程_zigbee network steering-程序员宅基地

文章浏览阅读3.4k次,点赞4次,收藏11次。转载请注明出处,谢谢!Newbit-Msming 2018-10-18ZigBee 3.0 EmberZNet EFR32MG 学习笔记-目录ZigBee 3.0 EmberZNet EFR32MG 学习笔记-9-Network Steering加网流程环境:Windows 10、Simplicity Studio 4SDK: EmberZnet SDK 6.4.0.0工程:新建..._zigbee network steering