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

📄 svrsock.cpp

📁 类似于QQ的聊天工具,分为客户端和服务器端,有共享空间,能发布公告,可传输文件
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// SvrSock.cpp: implementation of the CSvrSock class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "SvrSock.h"
//#include "DataBag.h"
#include <winbase.h>
#include "ServerFunc.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
//DWORD WINAPI ThreadProc(LPVOID lpParameter);

//CServerFunc CSvrSock::DealFunc;

/*---------------------------------------------------------------------------
 数据接收处理线程,此线程将处理所有服务器接收到的数据
 ---------------------------------------------------------------------------*/
DWORD WINAPI CSvrSock::RecvProc(LPVOID Param)
{	
	tagTmpInfo* pTmp = (tagTmpInfo*)Param;

	
	/////////////////////////
	CServerFunc	   DealFunc;
	CMsgBag        mbBag;
	//tagPacketParam pp;

	char buff[10240];

	/////////////////////////////////////////////////////////////////////////
	//接收数据包
	int ret = recv((pTmp->m_CurUserInfo).m_sClientSocket,
					buff, 10240, 0);

	/////////////////////////////////////////////////////////////////////////
	//接收数据发生错误或数据丢失
	if(SOCKET_ERROR == ret || 
	(long)strlen(buff) != (mbBag.GetPacketLen(CString(buff)) + 4))
	{
		return 0;
	}

	/////////////////////////////////////////////////////////////////////////
	//获取数据包命令
	long lOrderType = mbBag.GetOrderCode(CString(buff));

	//********功能处理已经添加到CServerFunc类里***********//
	switch(lOrderType)
	{
		////////////////////////////////////////////////////////////////////
		//注册处理
		case 1001:
		{
			DealFunc.DoRegister(Param,buff);		
			break;
		}

		////////////////////////////////////////////////////////////////////
		//登陆处理
		case 1002:
		{
			DealFunc.DoLoad(Param,buff);
			break;
		}

		case 1003:
		{
			break;
		}

		////////////////////////////////////////////////////////////////////
		//好友资料查询
		case 1004:
		{
			DealFunc.DoResearchUserInfo(Param, buff, false);
			break;
		}

		////////////////////////////////////////////////////////////////////
		//用户聊天
		case 1005://用户对聊
		{
			DealFunc.DoChat(Param, buff);
			break;
		}
		
		////////////////////////////////////////////////////////////////////
		//用户公告 [Add] dong 12-27
		case 1007:
		{
			char* strBuf = new char[strlen(buff) + 1];
			strcpy(strBuf, buff);
			::PostMessage(*(pTmp->m_hDlgWnd), WM_DEALSYSMSG, (WPARAM)strBuf, 1007); 
			break;
		}

		////////////////////////////////////////////////////////////////////
		//共享文件信息查询
		case 1009:
		{
			DealFunc.DoShareFile(Param, buff, false);
			break;
		}

		/////////////////////////////////////////////////////////////////////
		//个人资料修改
		case 1011:
		{
			DealFunc.DoModifyOwnInfo(Param, buff);
			break;
		}

		/////////////////////////////////////////////////////////////////////
		//用户资料查询
		case 1012:
		{
			DealFunc.DoResearchUserInfo(Param, buff, true);
			break;
		}

		////////////////////////////////////////////////////////////////////
		//个人文件信息查询
		case 1014:
		{
			DealFunc.DoShareFile(Param, buff, true);
			break;
		}

		default: break;
	}

	delete pTmp;
	return 0;
}


CSvrSock::CSvrSock()
{
	m_sServerSocket = NULL;
	m_bLintenStatus = FALSE;
	m_hMutex        = CreateMutex(NULL, 0, NULL);
}

CSvrSock::~CSvrSock()
{
	if(m_bLintenStatus)
	{
		closesocket(m_sServerSocket);
	}
}


/*---------------------------------------------------------------------------
 创建服务器函数--创建监听套接字,邦定监听套接字到本地IP和响应端口,建立监听
 ---------------------------------------------------------------------------*/
BOOL CSvrSock::CreatServer(HWND hDlgWnd, short nPort)
{
	m_hDlgWnd = hDlgWnd;

	if(!CSock::InitSock())
	{
		return FALSE;
	}
	m_sServerSocket           = CSock::m_sSock;
	
	SOCKADDR_IN addr;
	addr.sin_family           = AF_INET;
	addr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
	addr.sin_port             = htons(nPort);
	
	int ret = bind(m_sServerSocket, (sockaddr*)&addr, sizeof(SOCKADDR_IN));
	if(SOCKET_ERROR == ret)
	{
		AfxMessageBox("服务器套接字邦定失败!");
		return FALSE;
	}

	if(listen(m_sServerSocket, 5) == SOCKET_ERROR)
	{
		AfxMessageBox("服务器套接字监听失败!");
		return FALSE;
	}

	m_bLintenStatus = TRUE;

	///////////////////////////////////////////////////////
	//获取本地ip
	char hostName[256];
	CString strhostName;
	gethostname(hostName, 256);
	struct hostent FAR* pHostent = gethostbyname(hostName);
	memcpy(&addr.sin_addr, pHostent->h_addr_list[0], 4);
	
	///////////////////////////////////////////////////////////
	//添加服务器信息到链表中
	tagClientSockeInfo* pSvrInfo;	
	pSvrInfo = new tagClientSockeInfo;
	pSvrInfo->m_sClientSocket = m_sServerSocket;
	pSvrInfo->m_strIp         = inet_ntoa(addr.sin_addr);
	pSvrInfo->m_strUsrId      = "------";
	pSvrInfo->m_strUsrName    = "服务器";
	pSvrInfo->m_strFilePort   = "8000";
	m_pClntSockList.AddHead(pSvrInfo);
	
	///////////////////////////////////////////////////////
	//填充系统信息
	tagServerSysMsg* msg = new tagServerSysMsg;
	msg->strSydMsg[0].Format("%d", pSvrInfo->m_sClientSocket);
	msg->strSydMsg[1] = pSvrInfo->m_strUsrName;
	msg->strSydMsg[2] = pSvrInfo->m_strUsrId;
	msg->strSydMsg[3] = pSvrInfo->m_strFilePort;
	msg->strSydMsg[4] = pSvrInfo->m_strIp;
	msg->strSydMsg[5] = "服务器启动";
	PostMessage(m_hDlgWnd, WM_DEALSYSMSG, (WPARAM)msg, 0);
	return TRUE;
}


/*---------------------------------------------------------------------------
 连接响应处理函数:响应客户端的连接请求,连接请求成功后记录当前连接客户端的相应
 信息保存到tagClientSockeInfo结构体中,并将此结构体首地址加入链表。其中结构体的
 成员m_sClientSocket为连接成功创建的新套接字,用于当前客户端与服务器通信;m_strIp
 为客户端IP地址;m_strUserId为登陆用户名;m_strTime为当前用户登陆时间
 ---------------------------------------------------------------------------*/
BOOL CSvrSock::OnAccept()
{
	tagClientSockeInfo* pClient;	
	pClient = new tagClientSockeInfo;

	///////////////////////////////////////////////////////////////////////////
	//接受客户连接请求
	SOCKADDR_IN addr;
	int len = sizeof(SOCKADDR_IN);
	pClient->m_sClientSocket = accept(m_sServerSocket, (sockaddr*)&addr, &len);
	if(pClient->m_sClientSocket == INVALID_SOCKET)
	{
		return FALSE;
	}
	
	////////////////////////////////////////////////////////////
	//数据库维修,不允许客户连接,返回命令”9999“
	if(m_Cn.IsCnClose())
	{
		send(pClient->m_sClientSocket, "00009999", 8, 0);
		Sleep(10);
		closesocket(pClient->m_sClientSocket);
		delete pClient;
		return FALSE;
	}

	m_sCurClientSocket  = pClient->m_sClientSocket;

	///////////////////////////////////////////////////////////
	//初始化保存连接客户信息结构
	pClient->m_strIp      = inet_ntoa(addr.sin_addr);
	pClient->m_strFace     = CString("0");
	pClient->m_bOnLine    = false;
	pClient->m_strFilePort = CString("---");

	///////////////////////////////////////////////////////////
	//添加结构到链表中
	WaitForSingleObject(m_hMutex, INFINITE);
	m_pClntSockList.AddHead(pClient);
	ReleaseMutex(m_hMutex);

	return TRUE;
}


/*---------------------------------------------------------------------------
 数据接受处理函数:用于接收到达的网络数据包。此函数中将开新的线程对到达的数据
 包进行接收。新开的线程将传入一个结构体指针,此结构体成员:m_sCurSock为当前响
 应网络事件的客户端套接字(连接时在服务器端创建);m_pTmpList为指向链表对象
 m_pClntSockList的指针。
 ---------------------------------------------------------------------------*/

⌨️ 快捷键说明

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