网络协议笔记(一)

1.网络模型包含,OSI七层模型,TCP/IP模型

 

2.链路层,主要功能是在两个网络实体之间提供数据链路连接,其中主要使用的协议是ARP协议

 

3.网络层,主要作用是实现远程设备连接,其中主要使用协议是IP协议

 

4.传输层,主要是对数据包的分割,重组,排序,重传和连接保证数据准确到达另一端TCP/UDP

 

5.应用层,主要面对用户,常见协议,DNS,HTTP,POP3,SMTP,Telent

 

6.协议栈,一组协议系统工作

 

7.数据包分析和嗅探,主要功能是,收集网络链路上的二进制数据源,转换二进制可读形式,分析统计


windows下套接字编程

通过自己编写程序,实现对图片的简单加密(使用最简单加密方式xor)发送,在服务端接收到数据后进行解密,并正确显示,同时使用Wireshark进行抓包练习,抓取该数据包找到对应的图片数据,

Wireshark工具学习:《Wireshark 数据包分析实战(第二版)》

思路:1.完成程序的编写,

               服务端代码:WinSockDemo.cpp,

// WinSockDemo.cpp : 定义控制台应用程序的入口点。
//Server

//1.包含头文件及库
//2.初始化环境
//3.绑定
//4.监听
//5.接收
//6.收发消息

#include "stdafx.h"
#include <WinSock2.h>
#include <fstream>
#pragma comment(lib, "ws2_32.lib")
using namespace std;

//数据解密
char *XorData(char *pData, int nSize)
{
	for (int i = 0; i < nSize; i++)
	{
		pData[i] = pData[i] ^ 0x97;
	}
	return pData;
}

int _tmain(int argc, _TCHAR* argv[])
{
	//1.初始化环境
	WSADATA wsd = {};
	if (WSAStartup(MAKEWORD(2, 2), &wsd))
	{
		printf("初始化环境失败!");
		return 0;
	}
	//判断版本号
	if (!(LOBYTE(wsd.wVersion) == 2 &&
		HIBYTE(wsd.wVersion) == 2))
	{
		printf("版本号不匹配!");
		WSACleanup();
		return 0;
	}
	//2.创建套接字
	SOCKET sockServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (sockServer == INVALID_SOCKET)
	{
		printf("创建套接字失败!");
		WSACleanup();
		return 0;
	}
	//3.绑定地址端口号
	SOCKADDR_IN addrServer = {};
	addrServer.sin_family = AF_INET;
	addrServer.sin_addr.S_un.S_addr = inet_addr("192.168.1.245");// 192.168.43.110
	addrServer.sin_port = htons(1234);
	int nRet = bind(sockServer, (sockaddr*)&addrServer, sizeof(SOCKADDR_IN));
	if (nRet == SOCKET_ERROR)
	{
		printf("绑定失败!");
		closesocket(sockServer);
		WSACleanup();
		return 0;
	}
	//4.监听
	nRet = listen(sockServer, 5);
	if (nRet == SOCKET_ERROR)
	{
		printf("监听失败!");
		closesocket(sockServer);
		WSACleanup();
		return 0;
	}
	//5.接收连接
	SOCKADDR_IN addrClient = {};
	int nSize = sizeof(SOCKADDR_IN);
	SOCKET sockClient = accept(sockServer, (sockaddr*)&addrClient, &nSize);
	if (nRet == SOCKET_ERROR)
	{
		printf("连接失败!");
		closesocket(sockServer);
		WSACleanup();
		return 0;
	}
	//6.收消息
	nRet = send(sockClient, "Server:link success!", strlen("Server:link success!"), 0);
	if (nRet == SOCKET_ERROR)
	{
		closesocket(sockClient);
		closesocket(sockServer);
		WSACleanup();
		return 0;
	}
	//收消息
	CHAR recvBuf[1024] = {};
	nRet = recv(sockClient, recvBuf, 1024, 0);
	if (nRet == SOCKET_ERROR)
	{
		closesocket(sockClient);
		closesocket(sockServer);
		WSACleanup();
		return 0;
	}
	printf("%s", recvBuf);

	//接收由客户端发送的图片

	//创建文件
	CHAR szName[10] = {};
	sprintf_s(szName, "2.jpg");
	ofstream outFile(szName, ios_base::binary);
	//保存接收到的图片
	while (true)
	{
		char bufRecv[1024] = {};
		nRet = recv(sockClient, bufRecv, 1024, 0);
		//解密
		char *pData = XorData(bufRecv, nRet);
		if (nRet == SOCKET_ERROR)
		{
			break;
		}
		else if (nRet < 1024 && nRet>0)
		{
			//最后的数据
			outFile.write(pData, nRet);
			outFile.close();
			break;
			//continue;
		}
		else if (nRet == 1024)
		{
			//正常读取
			outFile.write(pData, nRet);
			//Sleep(100);
			//outFile.flush();
		}
	}

	closesocket(sockClient);
	closesocket(sockServer);
	WSACleanup();
	system("pause");
	return 0;
}

               客户端代码:WinSockDemoClient.cpp,

 

// WinSockDemoClient.cpp : 定义控制台应用程序的入口点。
//Client
//0.包含头文件及库
//1.初始化编程环境
//2.创建套接字
//3.连接
//4.收发消息

#include "stdafx.h"
#include <fstream>
#include <WinSock2.h>
#pragma comment(lib, "ws2_32.lib")
using namespace std;

//获取图片到缓冲区
char* ReadJpgFile(int &nSize)
{
	//打开文件
	ifstream inFile("1.jpg", ios_base::binary);
	//获取文件大小
	inFile.seekg(0, ios::end);
	nSize = (int)inFile.tellg();
	inFile.seekg(0, ios::beg);
	//读取文件
	char* pRead = new char[nSize]{};
	inFile.read(pRead, nSize);
	return pRead;
}

//数据加密
char *XorData(char *pData, int &nSize)
{
	for (int i = 0; i < nSize; i++)
	{
		pData[i] = pData[i] ^ 0x97;
	}
	return pData;
}

int _tmain(int argc, _TCHAR* argv[])
{
	//1.初始化编程环境
	WSADATA wsd = {};
	if (WSAStartup(MAKEWORD(2, 2), &wsd))
	{
		printf("初始化环境失败!");
		return 0;
	}
	//判断版本
	if (!(LOBYTE(wsd.wVersion) == 2 &&
		HIBYTE(wsd.wVersion) == 2))
	{
		printf("版本号检测失败!");
		WSACleanup();
		return 0;
	}
	//2.创建套接字
	SOCKET sockClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (sockClient == INVALID_SOCKET)
	{
		printf("创建套接字失败!");
		WSACleanup();
		return 0;
	}
	//3.连接服务器
	SOCKADDR_IN addrServer = {};
	addrServer.sin_family = AF_INET;
	addrServer.sin_addr.S_un.S_addr = inet_addr("192.168.1.245");// 192.168.43.110
	addrServer.sin_port = htons(1234);
	int nRet = connect(sockClient, (sockaddr*)&addrServer, sizeof(sockaddr));
	if (sockClient == SOCKET_ERROR)
	{
		printf("连接失败!");
		closesocket(sockClient);
		WSACleanup();
		return 0;
	}
	//4.收消息
	CHAR recvBuf[1024] = {};
	nRet = recv(sockClient, recvBuf, 1024, 0);
	if (nRet == SOCKET_ERROR)
	{
		closesocket(sockClient);
		WSACleanup();
		return 0;
	}
	printf("%s", recvBuf);
	//发消息
	nRet = send(sockClient, "Client:link success!", strlen("Client:link success!"), 0);
	if (nRet == SOCKET_ERROR)
	{
		closesocket(sockClient);
		WSACleanup();
		return 0;
	}

	//发送图片
	//1.读取文件到缓冲区
	int nSize = 0;
	char *pRead = ReadJpgFile(nSize);
	//数据加密
	char *pData = XorData(pRead, nSize);
	//2.发送图片
	while (true)
	{
		char p[1024] = {};
		memcpy(p, pData, 1024);
		nRet = send(sockClient, p, 1024, 0);
		pData += 1024;
		nSize -= 1024;
		if (nSize < 1024)
		{
			memcpy(p, pData, nSize);
			nRet = send(sockClient, p, nSize, 0);
			printf("发送图片完成!");
			delete[] pRead;
			delete[] pData;
			pRead = nullptr;
			pData = nullptr;

			closesocket(sockClient);
			WSACleanup();
			system("pause");
			return 0;
		}
	}
	closesocket(sockClient);
	WSACleanup();
	system("pause");
	return 0;
}

         2.打开Wireshark工具选择对应的网卡,开始进行抓包,由于直接在本机进行测试,因此直接添加过滤数据包条件ip.dst == 192.168.1.245 && ip.src == 192.168.1.245,过滤数据包,然后本机抓取本机数据包需要添加一条静态路由,使用命令route add 192.168.1.245 mask 255.255.255.255 192.168.1.1,即可抓取本地数据包。




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值