1. 程式人生 > 其它 >【工具】ubuntu16安裝sendip發包工具,模擬傳送tcp/udp/icmp報文

【工具】ubuntu16安裝sendip發包工具,模擬傳送tcp/udp/icmp報文

技術標籤:linuxlinuxubuntu

寫在開篇,最近因為測試需求,要使用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

sudoapt-getinstallsendip

原始碼下載地址:

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. -ifd x IP don't fragment flag (see README)

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

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

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

  23. -ionum x

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

  25. Default: (no options)

  26. -ioeol IP option: end of list

  27. -ionop IP option: no-op

  28. -iorr x

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

  30. -iots x

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

  32. -iolsr x

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

  34. -iosid x

  35. IP option: stream identifier

  36. -iossr x

  37. 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上獲取到的結果:

[email protected]:~$ 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。

[email protected]:~$ 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. #define MAXLINE 256

  16. #define PORT 6666

  17. int listenfd;

  18. int connfd;

  19. pthread_t read_id, write_id;

  20. /*

  21. linux ctrl + C 會產生 SIGINT訊號

  22. 接收到SIGINT 訊號進入該函式

  23. */

  24. void stop(int signo)

  25. {

  26. printf("stop\n");

  27. close(connfd);

  28. close(listenfd);

  29. _exit(0);

  30. }

  31. /*

  32. 當客戶端斷開連線的時候,

  33. 在服務端socket send程序可以收到收到訊號SIGPIPE,

  34. 收到SIGPIPE訊號進入該函式結束建立的執行緒。

  35. */

  36. void signal_pipe(int signo)

  37. {

  38. pthread_kill(read_id,SIGQUIT);//向read執行緒傳送SIGQUIT

  39. pthread_join(read_id,NULL); //阻塞執行緒執行,直到read 執行緒退出。

  40. close(connfd); //關閉連線

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

  42. pthread_exit(0); //結束write 執行緒

  43. }

  44. /*

  45. read 執行緒接收到SIGQUIT訊號,

  46. 執行執行緒退出操作

  47. */

  48. void pthread_out(int signo)

  49. {

  50. pthread_exit(0);

  51. }

  52. /*

  53. read 執行緒執行函式

  54. */

  55. void* read_func(void* arg)

  56. {

  57. char readbuff[MAXLINE];

  58. int n = 0;

  59. int fd;

  60. fd = *(int*)arg; /*main 主程序傳遞過來的連線檔案描述符*/

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

  62. signal(SIGQUIT,pthread_out); /* 註冊SIGQUIT 訊號*/

  63. while(1)

  64. {

  65. n = recv(fd, readbuff, MAXLINE, 0); /*recv 在這裡是阻塞執行*/

  66. if(n > 0)

  67. {

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

  69. }

  70. };

  71. }

  72. /*

  73. write 執行緒執行函式

  74. */

  75. void* write_func(void* arg)

  76. {

  77. char writebuff[MAXLINE];

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

  79. unsigned char i = 0;

  80. int num = 0;

  81. int fd;

  82. fd = *(int*)arg;

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

  84. signal(SIGPIPE,signal_pipe); /* 註冊 SIGPIPE訊號 */

  85. while(1)

  86. {

  87. sleep(1);

  88. send(fd,write,strlen(write)+1,0);/*向客戶端傳送資料*/

  89. }

  90. }

  91. int main(int argc, char** argv)

  92. {

  93. char buff[MAXLINE];

  94. int num;

  95. int addrlen;

  96. struct sockaddr_in server_addr; /*伺服器地址結構*/

  97. struct sockaddr_in client_addr; /*客戶端地址結構*/

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

  99. {

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

  101. exit(0);

  102. }

  103. /*設定服務端地址*/

  104. addrlen = sizeof(struct sockaddr_in);

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

  106. server_addr.sin_family = AF_INET; /*AF_INET表示 IPv4 Intern 協議*/

  107. server_addr.sin_addr.s_addr = htonl(INADDR_ANY); /*INADDR_ANY 可以監聽任意IP */

  108. server_addr.sin_port = htons(PORT); /*設定埠*/

  109. /*繫結地址結構到套接字描述符*/

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

  111. {

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

  113. exit(0);

  114. }

  115. /*設定監聽佇列,這裡設定為1,表示只能同時處理一個客戶端的連線*/

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

  117. {

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

  119. exit(0);

  120. }

  121. signal(SIGINT,stop); /*註冊SIGINT 訊號*/

  122. while(1)

  123. {

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

  125. if( (connfd = accept(listenfd, (struct sockaddr*)&client_addr, &addrlen)) == -1)/*接收客戶端的連線,這裡會阻塞,直到有客戶端連線*/

  126. {

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

  128. continue;

  129. }

  130. if(pthread_create(&read_id,NULL,read_func,&connfd))/*建立 read 執行緒*/

  131. {

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

  133. }

  134. if(pthread_create(&write_id,NULL,write_func,&connfd))/*建立 write 執行緒*/

  135. {

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

  137. }

  138. pthread_join(write_id,NULL); /*阻塞,直到write程序退出後才進行新的客戶端連線*/

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

  140. }

  141. }

客戶端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. #define MAXLINE 256

  16. #define PORT 6666

  17. int fd;

  18. /*

  19. linux ctrl + C 會產生 SIGINT訊號

  20. 接收到SIGINT 訊號進入該函式

  21. */

  22. void stop(int signo)

  23. {

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

  25. close(fd);

  26. _exit(0);

  27. }

  28. /*客戶端處理函式*/

  29. void client_process(void)

  30. {

  31. char readbuff[MAXLINE];

  32. char writebuff[MAXLINE];

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

  34. int num = 0;

  35. while(1)

  36. {

  37. num = recv(fd,readbuff,MAXLINE,0);/*接收服務端的資料,recv在這裡如果沒有資料會阻塞*/

  38. if(num > 0)

  39. {

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

  41. send(fd, write, strlen(write)+1, 0); /*接收到資料後再向服務端傳送一個字串*/

  42. }

  43. else if(num == 0)/*recv返回值為0 的時候表示服務端已經斷開了連線*/

  44. {

  45. stop(1); /*執行退出操作*/

  46. }

  47. }

  48. }

  49. int main(int argc, char** argv)

  50. {

  51. struct sockaddr_in server_addr;

  52. struct sockaddr_in client_addr;

  53. int ret;

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

  55. if(fd < 0)

  56. {

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

  58. }

  59. /*設定服務端地址*/

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

  61. server_addr.sin_family = AF_INET; /*AF_INET表示 IPv4 Intern 協議*/

  62. server_addr.sin_addr.s_addr = htonl(INADDR_ANY);/*INADDR_ANY 可以監聽任意IP */

  63. server_addr.sin_port = htons(PORT); /*設定埠*/

  64. inet_pton(AF_INET,argv[1],&server_addr.sin_addr);/*將使用者輸入的字串型別的IP地址轉為整型*/

  65. connect(fd,(struct sockaddr*)&server_addr,sizeof(server_addr));/*連線伺服器*/

  66. signal(SIGINT,stop); /*註冊SIGINT訊號*/

  67. client_process(); /*進入處理函式*/

  68. close(fd);/*關閉檔案*/

  69. return 0;

  70. }

Makefile:


  1. CC = gcc

  2. CPP = g++

  3. RM = rm -rf

  4. ## debug flag

  5. DBG_ENABLE = 1

  6. ## source file path

  7. SRC_PATH := .

  8. ## get all source files

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

  10. ## target exec file name

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

  12. ## all .o based on all .c

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

  14. ## need libs, add at here

  15. LIBS := pthread

  16. ## used headers file path

  17. INCLUDE_PATH := .

  18. ## used include librarys file path

  19. LIBRARY_PATH := /lib

  20. ## debug for debug info, when use gdb to debug

  21. ifeq (1, ${DBG_ENABLE})

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

  23. endif

  24. ## get all include path

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

  26. ## get all library path

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

  28. ## get all librarys

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

  30. all: clean build $(TARGET)

  31. build:

  32. gcc client.c -o client -lpthread

  33. gcc server.c -o server -lpthread

  34. clean:

  35. $(RM) $(OBJS) $(TARGET)

編譯:

[email protected]:~/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. #define MYPORT 8308

  10. #define ERR_EXIT(m) \

  11. do { \

  12. perror(m); \

  13. exit(EXIT_FAILURE); \

  14. } while (0)

  15. void echo_ser(int sock)

  16. {

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

  18. struct sockaddr_in peeraddr;

  19. socklen_t peerlen;

  20. int n;

  21. while (1)

  22. {

  23. peerlen = sizeof(peeraddr);

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

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

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

  27. if (n <= 0)

  28. {

  29. if (errno == EINTR)

  30. continue;

  31. ERR_EXIT("recvfrom error");

  32. }

  33. else if(n > 0)

  34. {

  35. printf("接收到的資料:%s\n",recvbuf);

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

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

  38. printf("回送的資料:%s\n",recvbuf);

  39. }

  40. }

  41. close(sock);

  42. }

  43. int main(void)

  44. {

  45. int sock;

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

  47. ERR_EXIT("socket error");

  48. struct sockaddr_in servaddr;

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

  50. servaddr.sin_family = AF_INET;

  51. servaddr.sin_port = htons(MYPORT);

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

  53. printf("監聽%d埠\n",MYPORT);

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

  55. ERR_EXIT("bind error");

  56. echo_ser(sock);

  57. return 0;

  58. }

客戶端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. #define MYPORT 8308

  11. char* SERVERIP = "127.0.0.1";

  12. #define ERR_EXIT(m) \

  13. do \

  14. { \

  15. perror(m); \

  16. exit(EXIT_FAILURE); \

  17. } while(0)

  18. void echo_cli(int sock)

  19. {

  20. struct sockaddr_in servaddr;

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

  22. servaddr.sin_family = AF_INET;

  23. servaddr.sin_port = htons(MYPORT);

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

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

  26. int ret;

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

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

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

  30. {

  31. printf("向伺服器傳送:%s\n",sendbuf);

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

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

  34. if (ret == -1)

  35. {

  36. if (errno == EINTR)

  37. continue;

  38. ERR_EXIT("recvfrom");

  39. }

  40. printf("從伺服器接收:%s\n",recvbuf);

  41. memset(sendbuf, 0, sizeof(sendbuf));

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

  43. }

  44. close(sock);

  45. }

  46. int main(void)

  47. {

  48. int sock;

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

  50. ERR_EXIT("socket");

  51. echo_cli(sock);

  52. return 0;

  53. }

Makefile檔案內容:


  1. CC = gcc

  2. CPP = g++

  3. RM = rm -rf

  4. ## debug flag

  5. DBG_ENABLE = 1

  6. ## source file path

  7. SRC_PATH := .

  8. ## get all source files

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

  10. ## target exec file name

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

  12. ## all .o based on all .cpp

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

  14. ## need libs, add at here

  15. LIBS := pthread

  16. ## used headers file path

  17. INCLUDE_PATH := .

  18. ## used include librarys file path

  19. LIBRARY_PATH := /lib

  20. ## debug for debug info, when use gdb to debug

  21. ifeq (1, ${DBG_ENABLE})

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

  23. endif

  24. ## get all include path

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

  26. ## get all library path

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

  28. ## get all librarys

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

  30. all: clean build $(TARGET)

  31. build:

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

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

  34. clean:

  35. $(RM) $(OBJS) $(TARGET)

執行:

先執行伺服器:

[email protected]:~/test/socket/udp$ ./service
監聽2368埠
Velodyne socket fd is 3

新建終端執行客戶端,並輸入hello:

[email protected]:~/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