使用原始套接字程式設計實現簡單的ping程式

2021-07-03 22:36:28 字數 2805 閱讀 5052

程式實現步驟:

1、初始化windows sockets網路環境

wsadata    wsa;

wsastartup(makeword(2,2),&wsa);

2、構造目的端socket位址

3、建立原始套接字

4、定義ip和icmp頭部資料結構

5、傳送報文

6、接收報文

其中icmp回顯請求與回顯應答報文結構如下圖:

ip資料報格式:

部分成員函式解釋:

1、socket sockraw=wsasocket(af_inet,sock_raw,protocol,null,0,0);

af_inet:代表通訊域是tcp/ip協議簇

sock_raw:代表要建立的套接字型別是原始套接字

protocol:指定協議型別,可取ipproto_icmp(icmp協議)\ipproto_igmp(igmp協議)\ipproto_tcp(tcp協議)\ipproto_udp(udp協議)\ipproto_ip(ip協議)\ipproto_ram(原始ip)

2、int setsockopt(socket s,int level,int optname,const char* optval,int optlen);

s(套接字): 指向乙個開啟的套介面描述字

level:(級別): 指定選項**的型別。

sol_socket: 基本套介面

ipproto_ip: ipv4套介面

ipproto_ipv6: ipv6套介面

ipproto_tcp: tcp套介面

optname(選項名): 選項名稱

optval(選項值): 是乙個指向變數的指標 型別:整形,套介面結構, 其他結構型別:linger{}, timeval

optlen(選項長度) :optval 的大小

返回值:標誌開啟或關閉某個特徵的二進位制選項

3、int sendto(int   sockfd,const   void*  msg, int   len ,  unsignde   int  flags,struct  sockaddr*  to,int   tolen);

sockfd:傳送方的資料報套接字描述符

msg:指向傳送快取區的指標

len:傳送快取區的長度

flags:傳送的方式,一般置0

tolen:結構sockaddr的長度

返回值:傳送成功的話返回實際傳送的位元組數,錯誤返回-1

4、int  recvefrom(int   sockfd,const   void*  buf, int   len ,  unsignde   int  flags,struct  sockaddr*  from,int   fromlen)

sockfd:接收方的資料報套接字描述符

buf:指向傳送快取區的指標

len:傳送快取區的長度

flags:接收的方式,一般置0

tolen:結構sockaddr的長度

返回值:傳送成功的話返回實際接收的位元組數,錯誤返回-1

校驗和計算方法(網際校驗和演算法):

將被校驗資料按16位劃分(如果被校驗的資料位元組長度為奇數,則在尾部的位元組補乙個位元組的0),然後對每16位分組求反碼和,最後將結果取反碼得到校驗和。

具體**及注釋如下:

// console_ping.cpp : 定義控制台應用程式的入口點。

//#include "stdafx.h"

#include "winsock2.h"

#include "winsock.h"

#pragma comment(lib,"ws2_32.lib")

//常量定義

const int max_icmp_packet_size=1024;//icmp報文最大長度(包括報頭)

const int def_icmp_data_size=32;//icmp報文預設資料字段長度

const int icmp_echo_request=8;//icmp型別字段,8表示請求回顯

typedef struct icmpheader;

typedef struct ipheader;

void fill_icmp_data(char * icmp_data,int datasize);//填充icmp資料報函式

ushort checksum(ushort * pbuf,int isize);//計算校驗和函式

void decode_resp(char *buf,int bytes,struct sockaddr_in *from);//接收報文後判斷是否是目的端回送的報文

int _tmain(int argc, _tchar* argv)

ushort checksum(ushort * pbuf,int isize)

if(isize)

cksum+=*(uchar*)pbuf;

cksum=(cksum>>16)+(cksum&0xffff);

cksum+=(cksum>>16);

return (ushort)(~cksum);

}void decode_resp(char *buf,int bytes,struct sockaddr_in *from)

linux sock raw原始套接字程式設計

sock raw原始套接字程式設計可以接收到本機網絡卡上的資料幀或者資料報,對與監聽網路的流量和分析是很有作用的.一共可以有3種方式建立這種socket 1.socket af inet,sock raw,ipproto tcp ipproto udp ipproto icmp 傳送接收ip資料報 ...

網路程式設計原始套接字

socket stream 流式套接字 socket dgram socket raw 原始套接字 ipproto ip ip協議 ipproto icmp internet控制訊息協議,配合原始套接字可以實現ping的功能 ipproto igmp internet 閘道器服務協議,在多播中用到 ...

使用原始套接字Raw Socket實現資料報嗅探

網路上隨時都流通了大量的資料報,我們要想實現抓包並分析,實現思路思路大概是 在合適的時候捕獲資料報,儲存到緩衝區,作為備用 然後,按照一定的結構和格式去讀取緩衝區的內容。由於各種公開的網路協議是已知的,所以對於資料報的分析就比較簡單。通常我們都是使用類似wireshark的抓包軟體嗅探資料報,這些抓...