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

📄 dddlqserverdlg.cpp

📁 vpn服务器的源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
long CDdDlqServerDlg::OnMySocket(WPARAM wParam, LPARAM lParam)
{
	// 取得有事件发生的套节字句柄
	SOCKET s = wParam;
	// 查看是否出错
	if(WSAGETSELECTERROR(lParam))
	{
		ddRemoveClient(s);
		closesocket(s);
		return 0;
	}
	// 处理发生的事件
	switch(WSAGETSELECTEVENT(lParam))
	{
		case FD_ACCEPT:		// 监听中的套接字检测到有连接进入
			if(m_nClient < MAX_SOCKET)
			{
				// 接受连接请求,新的套节字client是新连接的套节字
				SOCKET client = ::accept(s, NULL, NULL);
				// 设置新的套节字为窗口通知消息类型
				int i = WSAAsyncSelect(client, 
					m_hWnd, WM_MYSOCKET, FD_READ|FD_WRITE|FD_CLOSE);
				ddAddClient(client);
			}
			else
			{
				MessageBox("连接客户太多!");
			}
			break;
		case FD_CLOSE:		// 检测到套接字对应的连接被关闭。
			ddRemoveClient(s);
			closesocket(s);
			break;
		case FD_READ:		// 套接字接受到对方发送过来的数据包
		{
			
			// 取得对方的IP地址和端口号(使用getpeername函数)
			// Peer对方的地址信息
			sockaddr_in sockAddr;
			memset(&sockAddr, 0, sizeof(sockAddr));
			int nSockAddrLen = sizeof(sockAddr);
			getpeername(s, (SOCKADDR*)&sockAddr, &nSockAddrLen);
			// 转化为主机字节顺序
			int nPeerPort = ntohs(sockAddr.sin_port);
			// 转化为字符串IP
			CString sPeerIP = inet_ntoa(sockAddr.sin_addr);
			
			// 取得对方的主机名称
			// 取得网络字节顺序的IP值
			DWORD dwIP = inet_addr(sPeerIP);
			// 获取主机名称,注意其中第一个参数的转化
			hostent* pHost = gethostbyaddr((LPSTR)&dwIP, 4, AF_INET);
			char szHostName[256];
			strncpy(szHostName, pHost->h_name, 256);		 

			// 接受真正的网络数据
			char szText[1024] = { 0 };
			unsigned char ctrlWord;
			recv(s, szText, 1024, 0);
			ctrlWord = unsigned char (szText[0]);
			if(ctrlWord == 0X01)//dial request
				ddAnswerDialReq(s, szText);
			if(ctrlWord == 0X02)//client update
				ddxClientUpdate(szText);

			// 显示给用户
			//CString strItem = CString(szHostName) + "["+ sPeerIP+ "]: " + CString(szText);
//			m_listInfo.InsertString(0, strItem);
			break;
		}
	}
	return 0;
}

BOOL CDdDlqServerDlg::ddAddClient(SOCKET s)
{
	if(m_nClient < MAX_SOCKET)
	{
		// 添加新的成员
		m_arClient[m_nClient++] = s;
		return TRUE;
	}
	return FALSE;
}

void CDdDlqServerDlg::ddRemoveClient(SOCKET s)
{
	BOOL bFind = FALSE;
	for(int i=0; i<m_nClient; i++)
	{
		if(m_arClient[i] == s)
		{
			bFind = TRUE;
			break;
		}
	}

	// 如果找到就将此成员从列表中移除
	if(bFind)
	{
		m_nClient--;
		// 将此成员后面的成员都向前移动一个单位
		for(int j=i; j<m_nClient; j++)
		{
			m_arClient[j] = m_arClient[j+1];
		}
	}
}

void CDdDlqServerDlg::ddCloseAllSocket()
{
	// 关闭监听套节字
	if(m_socket != INVALID_SOCKET)
	{
		::closesocket(m_socket);
		m_socket = INVALID_SOCKET;
	}
	
	// 关闭所有客户的连接
	for(int i=0; i<m_nClient; i++)
	{
		::closesocket(m_arClient[i]);
	}
	m_nClient = 0;
}

void CDdDlqServerDlg::ddStartServer()
{
	if(m_socket == INVALID_SOCKET)  // 开启服务
	{
		// 取得端口号
		CString sPort = "2345";
//		GetDlgItem(IDC_PORT)->GetWindowText(sPort);
		int nPort = atoi(sPort);
		if(nPort < 1025 || nPort > 65535)
		{
			MessageBox("端口号错误!");
			return;
		}

		// 创建监听套节字,使它进入监听状态
		if(!ddCreateSocket(nPort))
		{
			MessageBox("启动服务出错!");
			return;
		}
		
		// 设置相关子窗口控件状态
	//	GetDlgItem(IDC_START)->SetWindowText("停止服务");
		m_bar.SetText(" 正在监听……", 0, 0);
	//	GetDlgItem(IDC_PORT)->EnableWindow(FALSE);
	}
	else				// 停止服务
	{
		// 关闭所有连接
		ddCloseAllSocket();

		// 设置相关子窗口控件状态
	//	GetDlgItem(IDC_START)->SetWindowText("开启服务");
		m_bar.SetText(" 空闲", 0, 0);
	//	GetDlgItem(IDC_PORT)->EnableWindow(TRUE);
	}
}

BOOL CDdDlqServerDlg::ddCreateSocket(int nPort)
{
	if(m_socket == INVALID_SOCKET)
		::closesocket(m_socket);

	// 创建套节字
	m_socket = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if(m_socket == INVALID_SOCKET)
		return FALSE;
	
	// 填写要关联的本地地址
	sockaddr_in sin;
	sin.sin_family = AF_INET;
	sin.sin_port = htons(nPort);
	sin.sin_addr.s_addr = INADDR_ANY;
	// 绑定端口
	if(::bind(m_socket, (sockaddr*)&sin, sizeof(sin)) == SOCKET_ERROR)
	{
		return FALSE;
	}

	// 设置socket为窗口通知消息类型
	::WSAAsyncSelect(m_socket, m_hWnd, WM_MYSOCKET, FD_ACCEPT|FD_CLOSE);
	// 进入监听模式
	::listen(m_socket, 5);

	return TRUE;
}

void ddGlSend2Client(SOCKET sckt, CString sData)
{
	if(sckt == INVALID_SOCKET)
	{
		return;
	}

	// 取得要发送的字符串
	CString sText;
//	GetDlgItem(IDC_TEXT)->GetWindowText(sText);
	sText = sData;
	// 添加一个“回车换行”
	// 注意,添加它并不是必须的,但是如果使用本软件作为客户端调试网络协议,
	// 比如SMTP、FTP等,就要添加它了。因为这些协议都要求使用“回车换行”作为一个命令的结束标记
	//sText += "\r\n";

	// 发送数据到客户端
	if(::send(sckt, sText, sText.GetLength(), 0) != -1)
	{
		//AddStringToList(sText, FALSE);
		//GetDlgItem(IDC_TEXT)->SetWindowText("");
	}
}

int CDdDlqServerDlg::ddAnswerDialReq(SOCKET s, char *szAnswerText)
{
	CString strTmp;
	CString urName, urPwd, urIP, urCurr;
	BOOL bSuccess;

	//strTmp = szAnswerText;
	ddParseRecvMsg(szAnswerText, urName, urPwd, urIP, urCurr);
	bSuccess = theApp.glFindPositionFromUserTable(urName);
	if(!bSuccess)
		return -1;
	//theApp.adoRstUser.GetFieldValue("ddUserName", strTmp);
	theApp.adoRstUser.GetFieldValue("ddUserPwd", strTmp);
	if(strTmp != urPwd)
		return -2;
	theApp.adoRstUser.GetFieldValue("ddUserIP", strTmp);
	if(strTmp != urIP)
		return -3;
	//theApp.adoRstUser.GetFieldValue("ddKaiHuYear", iy);
	//theApp.adoRstUser.GetFieldValue("ddKaiHuMonth", im);
	//theApp.adoRstUser.GetFieldValue("ddKaiHuDay", id);
	//theApp.adoRstUser.GetFieldValue("ddDaoQiYear", iy);
	//theApp.adoRstUser.GetFieldValue("ddDaoQiMonth", im);
	//theApp.adoRstUser.GetFieldValue("ddDaoQiDay", id);
	theApp.adoRstUser.GetFieldValue("ddCurrServer", strTmp);
	if(strTmp != urCurr)
		return -4;
	//theApp.adoRstUser.GetFieldValue("ddUserAd", userInfo.uiAdv);
	bSuccess = theApp.glFindPositionFromServerTable(urCurr);
	if(!bSuccess)
		return -5;
	//theApp.adoRstServer.GetFieldValue("servName", strTmp);
	//theApp.adoRstServer.GetFieldValue("servZaiXianRenShu", irenshu);
	//theApp.adoRstServer.GetFieldValue("servZongRenShu", irenshu);
	//theApp.adoRstServer.GetFieldValue("servStatus", strTmp);
	theApp.adoRstServer.GetFieldValue("vpnServerIP", urIP);
	theApp.adoRstServer.GetFieldValue("vpnUserName", urName);
	theApp.adoRstServer.GetFieldValue("vpnUserPwd", urPwd);
	if(ddFormatMessage(strTmp, urName, urPwd, urIP, urCurr) != 1)
		return -6;
	ddGlSend2Client(s, strTmp);

	return 1;
}

int CDdDlqServerDlg::ddxClientUpdate(char *szUpdateText)
{
	CString str;
	CString urName, urPwd, urIP, urCurr;

	str = szUpdateText;
	ddParseRecvMsg(szUpdateText, urName, urPwd, urIP, urCurr);
	
	return 1;
}

int CDdDlqServerDlg::ddFormatMessage(CString &strMsg, CString vpnName, CString vpnPwd, CString vpnIP, CString vpnCurr)
{
	char szText[70] = {0};
	int i, ilen;	
	
	ilen = vpnName.GetLength();
	if((ilen < 1) || (ilen > 14))
		return -1;
	szText[0] = char(0X82);//byte[0] 1 byte
	szText[1] = ilen;
	for(i=0; i<ilen; i++)
		szText[2 + i] = vpnName[i];
	for(i=ilen; i<14; i++)//填满14个字节byte[1-15] 15 bytes
		szText[2 + i] = '0';
	
	ilen = vpnPwd.GetLength();//byte[16-30] 15 bytes
	if((ilen < 1) || (ilen > 14))
		return -2;
	szText[16] = ilen;
	for(i=0; i<ilen; i++)
		szText[17 + i] = vpnPwd[i];
	for(i=ilen; i<14; i++)//填满14个字节
		szText[17 + i] = '0';

	ilen = vpnIP.GetLength();//byte[31-46] 16bytes
	if((ilen < 7) || (ilen > 15))
		return -3;
	szText[31] = ilen;
	for(i=0; i<ilen; i++)
		szText[32 + i] = vpnIP[i];
	for(i=ilen; i<15; i++)//填满15个字节
		szText[32 + i] = '0';

	ilen = vpnCurr.GetLength();//byte[47-67] 21 bytes
	if((ilen < 1) || (ilen > 14))
		return -4;
	szText[47] = ilen;
	for(i=0; i<ilen; i++)
		szText[48 + i] = vpnCurr[i];
	for(i=ilen; i<20; i++)//填满20个字节
		szText[48 + i] = '0';

	szText[68] = '\0';
	strMsg = szText;
	
	return 1;
}

int CDdDlqServerDlg::ddParseRecvMsg(char *szMsg, CString &userName, CString &userPwd, CString &userIP, CString &userCurr)
{
	CString strMsg;
	char szText[21] = {0};
	int i, ilen;	
	
	strMsg = szMsg;
	if(strMsg.GetLength() != 68)
		return -1;
	//ilen = ddInterface.itfUseName.GetLength();//byte[1-15] 15 bytes
	ilen = strMsg[1];
	for(i=0; i<ilen; i++)
		szText[i] = strMsg[2 + i];
	szText[i] = '\0';
	userName = szText;
	//ilen = ddInterface.itfPassword.GetLength();//byte[16-30] 15 bytes
	ilen = strMsg[16];
	for(i=0; i<ilen; i++)
		szText[i] = strMsg[17 + i];
	szText[i] = '\0';
	userPwd = szText;
	//ilen = ddGetIPAddress(str, strIPAddress);byte[31-46] 16 bytes
	ilen = strMsg[31];
	for(i=0; i<ilen; i++)
		szText[i] = strMsg[32 + i];
	szText[i] = '\0';
	userIP = szText;
	//ilen = ddInterface.itfServerCurrent.GetLength();//byte[47-67] 21 bytes
	ilen = strMsg[47];
	for(i=0; i<ilen; i++)
		szText[i] = strMsg[48 + i];
	szText[i] = '\0';
	userCurr = szText;
	
	return 1;
}

⌨️ 快捷键说明

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