⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sock.cpp

📁 一个与金融方面有关的问题
💻 CPP
字号:
/******************************************************
网络类,用于各个模块在发送和接收数据时调用
作者:颜永华
*******************************************************/
#include "StdAfx.h"
#include ".\sock.h"
#include "BlowFish.h"
#include "MD5.h"
#include "OPCODE.H"

extern CLIENT_STATUS	clientStatus;

CSock::CSock(void)
{
	::ZeroMemory(Key.SendKey,8);
	::ZeroMemory(Key.RecvKey,8);
}

CSock::~CSock(void)
{
}
int CSock::sendPacket(BYTE *packet,int len)
{//发送封包
	int packetLen=len+9;
	BYTE *pPack=(BYTE*)malloc(sizeof(BYTE)*(packetLen));
	//加密封包
	EnCodeFlow(Key.SendKey,Key.SendKey,packet,pPack,len,0X11);

	int i=send(sock,(char*)pPack,packetLen,0);
	free(pPack);
	if(i!=packetLen)
		return 0;
	return 1;
}
int CSock::RetFlag()
{
	//拆包
	CHAR RetFlagBuff[6];
	int len=recv(sock,(char*)RetFlagBuff,sizeof(RETFLAG)+1,0);
	
	LPRETFLAG RetFlag=(LPRETFLAG)RetFlagBuff;
	if(len+1==sizeof(RETFLAG))
	{//控制 看是那个操作的返回
		switch(_OPCODE(RetFlag))
		{
		case SERVER_FIRST_REG:
			return	RetFlag->bFlag;
		case SERVER_LOGIN://成功显示信息
			if(RetFlag->bFlag==FLAG_SUCCEED)
			{	//登陆成功 请求显示封包
				//打包
				REQSHOW reqShow;
				memset(&reqShow,0,sizeof(REQSHOW));
				reqShow.wCode=CLIENT_SHOW_INFO;
				reqShow.wLen=sizeof(REQSHOW);
				strcpy(reqShow.customerName,clientStatus.cUserName);
				if(sendPacket((BYTE*)&reqShow,sizeof(REQSHOW)))
				{//保存接收到的显示数据,维护用户信息结构
					char showBuff[sizeof(SHOW_INFO_PACKET)];
					len=recv(sock,showBuff,sizeof(SHOW_INFO_PACKET),0);
					if(len+1==sizeof(SHOW_INFO_PACKET))
					{//保存状态信息
						LPSHOW_INFO_PACKET pShow=(LPSHOW_INFO_PACKET)showBuff;
						strcpy(clientStatus.Addr,pShow->Addr);
						strcpy(clientStatus.Email,pShow->Email);
						strcpy(clientStatus.Phone,pShow->Phone);
						strcpy(clientStatus.RealName,pShow->RealName);
						strcpy(clientStatus.RegBankIP,pShow->RegBankIP);
						clientStatus.nGrade=pShow->nGrade;
						clientStatus.nScore=pShow->nScore;
					}

				}

			}return RetFlag->bFlag;
		case SERVER_INMONEY:
			return	RetFlag->bFlag;
		case SERVER_OUTMONEY:
			return	RetFlag->bFlag;
		case SERVER_TRANSFER:
			return	RetFlag->bFlag;
		case SERVER_NOTIFY_PASSWORD:
			return	RetFlag->bFlag;
		default:
			return -1;
		}

	}else
		return -1;

}

int CSock::connectServer()
{
	//连接服务器
	sock=WSASocket(AF_INET,SOCK_STREAM,IPPROTO_TCP,NULL,0,WSA_FLAG_OVERLAPPED);
	//定义地址结构
	sockaddr_in addr;
	addr.sin_family=AF_INET;
	addr.sin_addr.S_un.S_addr=inet_addr("192.168.0.136");
	addr.sin_port=htons(8888);

	if(SOCKET_ERROR==(::connect(sock,(sockaddr*)&addr,sizeof(addr))))
	{
		::MessageBox(NULL,"连接服务器失败!","系统提示",0);
		return 0;
	}
	//接收密钥
	recv(sock,(char*)Key.RecvKey,8,0);   
	recv(sock,(char*)Key.SendKey,8,0);
	//解密KEY
	DeCodeKey(Key.RecvKey);
///////////
	/*CString str;
	for(int i=0;i<8;i++)
	{str.Format("-%02X",Key.RecvKey[i]);
	::OutputDebugString(str);}*/
//////////
	DeCodeKey(Key.SendKey);
///////
	/*for(int i=0;i<8;i++)
	{str.Format("-%02X",Key.SendKey[i]);
	::OutputDebugString(str);}*/
//////
	return 1;
}
void CSock::disconnectServer()
{	//断开连接
	closesocket(sock);
	sock=INVALID_SOCKET;
}
int CSock::recvpacket(char *packet,int len)
{
	return recv(sock,packet,len,0);//返回接收到的接收字节数
}
void CSock::recvReturnUserInfo(char userName[],char pwd[],char UserClass[],
			            char UserPoint[],char IPAddr[],char Phone[],char UserId[])
{
	//接收返回用户信息
	char buff[70];
	::recv(sock,buff,70,0);
	buff[68]='\0';
	//memcpy(realName,&buff[0],10);
	memcpy( UserId,buff,18);
	memcpy(Phone,&buff[18],15);
	memcpy(IPAddr,&buff[33],15);
	memcpy(UserPoint,&buff[48],10);
	memcpy(UserClass,&buff[58],10);
}

//利用key产生动态vkey
//
void CSock::ProduceNewKey(const BYTE *key, BYTE *vkey)
{
	int a, b;
	//b = (int)&a;                      //读取局部变量地址
	__asm lea eax, a;
	__asm mov ebx, [ebp + 4];
	//__asm mov ebx, [ebx + 4];         //读取二级返回地址
	__asm mov ecx, vkey;
	__asm mov word ptr [ecx], ax;
	__asm mov word ptr [ecx + 4], bx;
	__asm lea eax, b;
	__asm mov ebx, [ebp];
	__asm mov ebx, [ebx + 4];           //读取二级返回地址
	__asm mov word ptr [ecx + 6], ax;
	__asm mov word ptr [ecx + 2], bx;
	//*(int *)vkey = b;
	//*(int *)(vkey + 4) = (int)&b;
	
	for(int i = 0; i < 8; i++)       //key前4个字节和局部变量地址异或产生vkey前4个字节
		vkey[i] ^= key[i];           //,key后4个字节和二级返回地址异或产生vkey后四个字节
}

//利用key产生vkey所要插入封包的位置放在pos[8]中
void CSock::position(const BYTE *key, BYTE *pos, int len)
{
	for(int i = 0; i < 8; i++)        //得到8个插入位置(0-100,100为长度)
		pos[i] = key[i] % (len + 9);
	for(int i = 0; i < 8; i++)        //如果插入位置为0的话改成1
		if(0 == pos[i])pos[i] = 1;
}

//按pos位置把vkey插入到封包中再次打包放在outChar中
void CSock::ReWriteBag(const BYTE *pos, const BYTE *vkey, const BYTE *inChar, BYTE * outChar, int len, BYTE flag)
{
	outChar[len + 8] = flag;              //把标志位插入outChar[len+9]最后一个字节
	for(int i = 0; i < len; i++)                  //首先把数据密文拷贝到outChar[108]中,预留了8个字节存放动态vkey
		outChar[i] = inChar[i];         
	int currentLen = len;
	for(int i = 0; i < 8; i++)                   //8个字节一个一个插入,从左到右插入
	{
		if(pos[i] > currentLen) outChar[pos[i] - 1] = vkey[i];      //如果插入位置大于当前长度,就不必移动其它字节
		else                                                 //否则就要移动其它字节空出一个字节以便插入了
		{
			for(int j = currentLen; j >= pos[i]; j--)               //移动其它字节
				outChar[j] = outChar[j - 1];
			outChar[j] = vkey[i];                            //插入
		}
		currentLen++;                                              //当前长度加1
	}
}

//按照pos位置从封包中取出vkey[8],剩下的数据放在inChar中
void CSock::ReduceBag(const BYTE *pos, BYTE *outChar, BYTE *vkey, BYTE *inChar, int len)
{
	int currentLen = len + 8;
	for(int i = 7; i >= 0; i--)                //取出vkey,共8个字节,一个一个取,从右到左取出
	{
		vkey[i] = outChar[pos[i] - 1];         //首先要取出的放到vkey中去
		for(int j = pos[i]; j <= currentLen - 1; j++) //每取出一个字节就要把后面的字节一个一个移上来
			outChar[j - 1] = outChar[j];
		currentLen--;                                 //当前长度减1
	}
	for(int i = 0; i < len; i++)               //取出vkey后的封包放到inChar[100]中去,此时inChar就是取出了vkey的密文了
		inChar[i] = outChar[i];
}

//对数据包进行加密
void CSock::EnCode(const BYTE *key, BYTE *inChar, int len)
{
	for(int i = 0; i < len; i++)
		inChar[i] ^= key[i % 8];
}


//对数据包进行解密,加密算法的逆序
void CSock::DeCode(const BYTE *key, BYTE *inChar, int len)
{
	for(int i = 0; i < len; i++)
		inChar[i] ^= key[i % 8];
}

//填充客户端和服务器端交互所用到的key
void CSock::FillinKey(BYTE *key, const BYTE *vkey)
{
	for(int i = 0; i < 8; i++)
	//	key[i] = vkey[i];
	{
		__asm mov edi, vkey;
		__asm mov esi, key;
		__asm add edi, i;
		__asm add esi, i;
		__asm mov al, byte ptr [edi];
		__asm mov byte ptr [esi], al;
	}
}



//发包时:
//DataPack存放着原数据
//len为DataPack封包长度,HandlePack长度为(len+9),标志位插在最后一个字节里
void CSock::EnCodeFlow(BYTE *key, BYTE *vkey, BYTE *DataPack, BYTE *HandledPack, int len, BYTE flag)
{
	BYTE pos[8];
	EnCode(key, DataPack, len);  //加密数据包
	if(0x13 == flag)
	{
		ProduceNewKey(key, vkey);  //产生动态vkey
		position(key, pos, len);    //利用key产生插入位置放在pos[8]中
		ReWriteBag(pos, vkey, DataPack, HandledPack, len, flag);  //重新打包放在HandledPack[len+9]中
		FillinKey(key, vkey);
	}
	else
	{
		for(int i = 0; i < len; i++)
			HandledPack[i] = DataPack[i];
		HandledPack[len + 8] = flag;
	}
	//HandledPack中存放着密文
}
//接包时:
//HandledPack存放着密文
//len为DataPack封包长度,HandlePack长度为(len+9)
BYTE CSock::DeCodeFlow(BYTE *key, BYTE *vkey, BYTE *DataPack, BYTE *HandledPack, int len)	
{
	BYTE flag = HandledPack[len + 8];
	if(0x13 == flag)       //如果是最后一个包就要从里面取出动态密钥
	{
		BYTE pos[8];
		position(key, pos, len);      //利用key产生插入位置放在pos[8]中
		ReduceBag(pos, HandledPack, vkey, DataPack, len);  //把要交换的动态密钥从HandledPack抽出放到vkey去,抽出后的HandledPack存到DataPack中去
	}
	else                          //如果不是最后一个包就不要取密钥
	{
		for(int i = 0; i < len; i++)
			DataPack[i] = HandledPack[i];
	}

	DeCode(key, DataPack, len);    //对DataPack包解密
	FillinKey(key, vkey);   //用接受到的动态vkey填充key
	return flag;
	//DataPack中存放着明文
}

//连接时从服务器端接受的key进行解密
void CSock::DeCodeKey(BYTE *key)
{
	char var_array[10] = "dengchong";
	//for(int i = 0; i < 8; i++)
	//	scanf("%c", &var_array[i]);
		//cin>>var_array[i];
	for(int i = 0; i < 8; i++)
		key[i] ^= var_array[i];
}

//加密金钱数据
void CSock::EnCodeMoney(BYTE *key, BYTE *vkey, BYTE *DataPack, BYTE *HandledPack)
{
	BYTE pos[8];
	BlowFish BF;
	BF.gBlowFishInit(key);
	BF.gBlowFishEnCode(DataPack, DataPack);
	ProduceNewKey(key, vkey);
	position(key, pos, 8);
	ReWriteBag(pos, vkey, DataPack, HandledPack, 8, 0x13);
	FillinKey(key, vkey);
}

void CSock::DeCodeMoney(BYTE *key, BYTE *vkey, BYTE *DataPack, BYTE *HandledPack)
{
	BYTE pos[8];
	position(key, pos, 8);
	ReduceBag(pos, HandledPack, vkey, DataPack, 8);
	BlowFish BF;                                    
	BF.gBlowFishInit(key);                  
	BF.gBlowFishDeCode(DataPack, DataPack);
	FillinKey(key, vkey);
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -