1. 程式人生 > >原始套接字,接收所有資料的設定方法,及程式碼。

原始套接字,接收所有資料的設定方法,及程式碼。

<img src="https://img-blog.csdn.net/20150320091844253?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvU3RheV9EZWVw/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="" />在看一本安全程式設計書的時候讀到原始套接字地方,自己也嘗試寫了下來,將遇到的一個問題發出來。
// 原始套接字資料的接收.cpp : 定義控制檯應用程式的入口點。
//

#include "stdafx.h"
#include "stdio.h"

#include "Winsock2.h"
#include <ws2tcpip.h>
#include "mstcpip.h"
#pragma comment(lib,"ws2_32.lib")
typedef struct IpHeader
{
	unsigned char Version_HLen;      //首部長度和IP版本號
	unsigned char TOS;                //服務型別TOS
	unsigned short Length;           //總長度
	unsigned short Ident;            //標識
	unsigned short Flags_Offset;     //標誌位
	unsigned char TTL;               //生存時間TTL
	unsigned char Protocol;          //協議
	unsigned short Checksum;         //IP首部校驗和
	unsigned int SourceAddr;         //源IP地址
	unsigned int DestinationAddr;    //目的IP地址
}Ip_Header;
int _tmain(int argc, _TCHAR* argv[])
{
	WSADATA wsaData;
	Ip_Header *ip;

	//int Timeout=1000;   //設定超時
	SOCKET ReceiveSocket; //接收資料包的套接字
	char RecvBuffer[1024]; //用於接收資料
	sockaddr_in addr;   //地址結構
	int Len=sizeof(addr);
	int Result;
	if(Result=WSAStartup(MAKEWORD(2,2),&wsaData))
	{
		printf("WSAStartup failed with error %d\n",Result);
		return 0;
	}
	ReceiveSocket=socket(AF_INET,SOCK_RAW,IPPROTO_IP);
	if(ReceiveSocket==INVALID_SOCKET)
	{
		printf("socket failed with error %d\n",WSAGetLastError());
		return 0;
	}
	char Name[255];
	Result=gethostname(Name,255);//獲取本機IP地址
	if(Result==SOCKET_ERROR)
	{
		printf("gethostname failed with error %d\n",WSAGetLastError());
		return 0;
	}
	struct hostent *pHostent;
	pHostent=(struct hostent*)malloc(sizeof (struct hostent));
	pHostent=gethostbyname(Name);
	SOCKADDR_IN sock;
	sock.sin_family=AF_INET;
	sock.sin_port=htons(5555);
	memcpy(&sock.sin_addr.S_un.S_addr,pHostent->h_addr_list[0],pHostent->h_length);
	

	Result=bind(ReceiveSocket,(PSOCKADDR)&sock,sizeof(sock));
	if(Result==SOCKET_ERROR)
	{
		printf("bind ReceiveSocket failed with error %d\n",WSAGetLastError());
		closesocket(ReceiveSocket);
		return 0;
	}
	
	DWORD dwBufferLen[10];
	DWORD dwBufferInLen=1;
	DWORD dwBytesReturned=0;

	Result=WSAIoctl(ReceiveSocket,SIO_RCVALL,&dwBufferInLen,sizeof(dwBufferInLen),&dwBufferLen,sizeof(dwBufferLen),&dwBytesReturned,NULL,NULL);
	if(Result==SOCKET_ERROR)
	{
		printf("WSAIoctl failed with error %d\n",WSAGetLastError());
		return 0;
	}

	while(1)  //迴圈接收資料
	{
		memset(RecvBuffer,0,sizeof(RecvBuffer)); //接收資料緩衝區清零
		memset(&addr,0,sizeof(addr));//對地址結構清零
		Result=recvfrom(ReceiveSocket,RecvBuffer,1024,0,(sockaddr*)&addr,&Len);

		if(Result==SOCKET_ERROR)
		{
			printf("recvfrom failed with error %d\n",WSAGetLastError());
			return 0;
		}
		static int number=0; //接收的網路資料包的個數
		number++;
		printf("Packet Number:%d\n",number);
		ip=(Ip_Header*)RecvBuffer;
		struct in_addr a;
		a.s_addr=ip->SourceAddr; //資料包的源IP地址
		printf("ip source ip:%s\n",inet_ntoa(a)); //整形IP地址轉換成字串形式
		a.s_addr=ip->DestinationAddr;//資料包的目的IP地址
		printf("ip Destination IP:%s\n",inet_ntoa(a));
		printf("protocol:%d\n",ip->Protocol); //分析協議型別

	}
	if(closesocket(ReceiveSocket)==SOCKET_ERROR)
	{
		printf("closesocket failed with error %d\n",WSAGetLastError());
		return 0;
	}
	if(WSACleanup()==SOCKET_ERROR)
	{
		printf("WSACleanup failed with error %d\n",WSAGetLastError());
		return 0;
	}
	return 0;
}
#include "mstcpip.h"   這個 標頭檔案要放在最後,因為他的定義是在前面檔案中實現的,也是我這次遇到的問題,反覆編譯不通過,提示變數未定義,我就納悶了,變數是標頭檔案裡面的怎麼沒定義,後來仔細看是標頭檔案的順序錯了。