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

📄 netmsgserverdlg.cpp

📁 这是聊天系统的服务器端
💻 CPP
📖 第 1 页 / 共 2 页
字号:

			//如果该用户已经上线,就从在线用户列表中清除他
			for(i=0;i<g_ouIndex;i++)
			{
				if(g_onlineUser[i].pSI == pSI_OU)
				{
					break;
				}
			}

			if(i < g_ouIndex)
			{
				for(DWORD j=i;j<g_dwEventTotal-1;j++)
				{
					g_onlineUser[j] = g_onlineUser[j+1];
				}

				g_onlineUser[j-1].id = 0;
				strcpy(g_onlineUser[j-1].ip,_T(""));
				g_onlineUser[j-1].pSI = NULL;
				g_ouIndex--;
			}
				
			GlobalFree(pSI);
			g_dwEventTotal--;
			continue;
		}

		// 已经有数据传递
		if( pSI->nStatus == WSA_RECV )
		{

			memcpy(&pSI->buffRecv[pSI->dwBytesRecv],pSI->wsaBuf.buf,dwBytesTransferred);
			pSI->dwBytesRecv+=dwBytesTransferred;
			memset(temp,0,sizeof(temp));
			sprintf(temp,"接受%s: %s",pSI->ip,pSI->buffRecv);
			dlg->m_list.InsertString(g_dwListCount++,temp);
			dlg->m_list.SetTopIndex(g_dwListCount-1);
			

			if((pSI->buffRecv[pSI->dwBytesRecv-2]='\t') && (pSI->buffRecv[pSI->dwBytesRecv-1]='\n') &&
				dwBytesTransferred>2)
			{
				if(pSI->bLoggedIn == FALSE)
				{

					if(LoginIn(pSI)==LOGGED_IN)
					{
						pSI->bLoggedIn = TRUE;
					}
										
				}
				else
				{
					if(DealCommand(pSI)==NETMSG_QUIT)
						continue;
				}
				memset( pSI->buffRecv,0,sizeof(pSI->buffRecv) );
				pSI->dwBytesRecv = 0;

			}
		}
		else
		{
			pSI->dwBytesSend += dwBytesTransferred;
		}
		
 		// 继续接收以后到来的数据
		if( RecvReq( pSI ) == -1 ) 
			return -1; 
		
	}
	AfxEndThread(0);
	return 0;

}
//发送数据
int SendRes( LPSOCKET_INF pSI )
{
	static DWORD dwSendBytes = 0;
	pSI->nStatus = WSA_SEND;
    memset(&(pSI->o), 0,sizeof(WSAOVERLAPPED));
    pSI->o.hEvent = g_events[g_index - WSA_WAIT_EVENT_0];
    pSI->wsaBuf.buf = pSI->buffSend + pSI->dwBytesSend;
    pSI->wsaBuf.len = strlen( pSI->buffSend ) - pSI->dwBytesSend;
    if (WSASend(pSI->s, &(pSI->wsaBuf), 1,&dwSendBytes,
		        0,&(pSI->o), NULL) == SOCKET_ERROR) 
	{
        if (WSAGetLastError() != ERROR_IO_PENDING) 
		{
			PrintSystemError("WSASend()失败");
			return -1;
        }
    }
	
	return 0;
}
//接受数据
int RecvReq( LPSOCKET_INF pSI )
{
	static DWORD dwRecvBytes = 0;	
	pSI->nStatus = WSA_RECV;	

	DWORD dwFlags = 0;
	memset(&(pSI->o), 0,sizeof(WSAOVERLAPPED));
	pSI->o.hEvent = g_events[g_index - WSA_WAIT_EVENT_0];
	pSI->wsaBuf.len = DATA_BUFSIZE;

	if (WSARecv(pSI->s, &(pSI->wsaBuf), 1, &dwRecvBytes,
                &dwFlags,&(pSI->o), NULL) == SOCKET_ERROR)
	{
		if (WSAGetLastError() != ERROR_IO_PENDING)
		{
			PrintSystemError("WSARecv()失败");
			return -1;
		}
	}
	return 0;
}

int LoginIn(LPSOCKET_INF pSocketInf)
{
	LPSOCKET_INF pSI = pSocketInf;
	static char szUser[MAX_NAME_LEN];
	static char szPwd[MAX_PWD_LEN];
    int nRetVal = -1;
	CString strSQL;
	CString strNickname;


	CNetMsgServerDlg *dlg=(CNetMsgServerDlg*) AfxGetApp()->GetMainWnd();

	//注册
	if(strstr(strupr(strdup(pSI->buffRecv)),"REGT")!=NULL)
	{
		nRetVal = RegisterUserInfo( pSI );
		return nRetVal;
	}
	
	//输入用户名
	if(strstr(strupr(strdup(pSI->buffRecv)),"USER")!=NULL)
	{
		sprintf(szUser,"%s",pSI->buffRecv+strlen("USER")+1);		
		strtok( szUser,"\t\n");//注意,字符串szUser已经改变
		return nRetVal;
	}
	
	//输入密码
	if(strstr(strupr(strdup(pSI->buffRecv)),"PASS")!=NULL)
	{
		sprintf(szPwd,"%s",pSI->buffRecv+strlen("PASS")+1);		
		strtok( szPwd,"\t\n");//注意,字符串szUser已经改变


		//检查用户名
		long userID = 0;
		userID = atoi(szUser);
		strSQL=_T("");
		strSQL.Format("Select * FROM userinfo WHERE id = %d",userID);
		
		try{

			//如果记录集已打开,则关闭它
			if(dlg->m_pSet->IsOpen())
				dlg->m_pSet->Close();
			//打开记录集
			dlg->m_pSet->Open(CRecordset::dynaset,strSQL);
	
			if(!(dlg->m_pSet->IsEOF()))
			{			
				CString strPassword;
				dlg->m_pSet->GetFieldValue("nickname",strNickname);
				dlg->m_pSet->GetFieldValue("password",strPassword);

				if(strcmp(szPwd, strPassword) !=0)
				{
					//密码错误
					sprintf(pSI->buffSend,"%d",LOGIN_FAILED_AT_PWD);
					nRetVal = LOGIN_FAILED_AT_PWD;
				}
				else
				{
					//密码正确
					sprintf(pSI->buffSend,"%d",LOGGED_IN);
					nRetVal = LOGGED_IN;
					if(g_ouIndex >= MAX_ONLINE_NUM)//在线用户太多
					{
						sprintf(pSI->buffSend,"%d",LOGIN_FAILED_TOOMANY_ONLINEUSER);
						nRetVal = LOGIN_FAILED_TOOMANY_ONLINEUSER;
					}
					else
					{

						for(DWORD i=0;i<g_ouIndex;i++)
						{
							if(g_onlineUser[i].id == userID)//已经登陆了
							{
								sprintf(pSI->buffSend,"%d",LOGIN_FAILED_BECAUSE_LOGAGAIN);
								nRetVal = LOGIN_FAILED_BECAUSE_LOGAGAIN;
								break;
							}
						}
						
					}

				}

			}
			else
			{
				//该用户不存在
				sprintf(pSI->buffSend,"%d",LOGIN_FAILED_AT_ID);
				nRetVal = LOGIN_FAILED_AT_ID;
			}

			dlg->m_pSet->Close();
		}
		catch(CDBException *e)
		{
			sprintf(pSI->buffSend,"%d",LOGIN_FAILED_BECAUSE_DB);
			nRetVal = LOGIN_FAILED_BECAUSE_DB;
			PrintSystemError(e->m_strError);
		}
		if(SendRes( pSI ) == -1) 
			return -1;		
		
	}

	//如果登陆成功,增加在线用户列表
	if(nRetVal == LOGGED_IN)
	{
		g_onlineUser[g_ouIndex].id=atoi(szUser);
		strcpy(g_onlineUser[g_ouIndex].nickname,strNickname);
		strcpy(g_onlineUser[g_ouIndex].ip,pSI->ip);
		g_onlineUser[g_ouIndex++].pSI = pSI;

	}
	return nRetVal;
	
}

int RegisterUserInfo( LPSOCKET_INF pSI )
{

	char buff[MAX_BUFF_SIZE];
	USER_INF userInf;
	long nId = 0;
	CString strSQL;
	int	nRetVal = -1;
	memset(&userInf,0,sizeof(userInf));
	CNetMsgServerDlg *dlg=(CNetMsgServerDlg*) AfxGetApp()->GetMainWnd();

		//接收修注册信息
		memset(&userInf,0,sizeof(userInf));
		if(recv(pSI->s,(char *)&userInf,sizeof(userInf),0) == SOCKET_ERROR)
		{
			closesocket(pSI->s);
			PrintSystemError("REGT recv命令出错");
			return 1;
		}

		//获得要注册的ID值,他的值是最大值+1,如果记录为空,就设id为1000;
		strSQL=_T("");
		strSQL.Format("SELECT id FROM userinfo");	
		try
		{
			if(dlg->m_pSet->IsOpen())
				dlg->m_pSet->Close();
		    if ( ! dlg->m_pSet->IsOpen()) // if the recordset isn't already open..
		         dlg->m_pSet->Open(CRecordset::dynaset, strSQL); 
			if(!dlg->m_pSet->IsEOF())		
				dlg->m_pSet->MoveFirst();

			CString strTempId;
			if(!dlg->m_pSet->IsEOF())
			{		
				dlg->m_pSet->GetFieldValue("id",strTempId);
				nId = atoi(strTempId);
			}
		
			if(!dlg->m_pSet->IsEOF())
				dlg->m_pSet->MoveNext();
			while(!dlg->m_pSet->IsEOF())
			{
				dlg->m_pSet->GetFieldValue("id",strTempId);
				if(atoi(strTempId)>nId)
					nId = atoi(strTempId);
				dlg->m_pSet->MoveNext();
			
			}

		}
		catch(CDBException *e)
		{
			PrintSystemError(e->m_strError);
			nRetVal = REGT_FAIL_BECAUSE_DBREAD; //注册读数据库失败
		}	
		
		//如果读成功就可以写了
		if(nRetVal != REGT_FAIL_BECAUSE_DBREAD)
		{
			nId++;
			if(nId==1)
				nId=1000;//初始值
		
			userInf.id =nId;
			//数据库操作存储记录
			strSQL = _T("");
			strSQL.Format("insert into userinfo(id,nickname,sex,age,address,password) values(%ld,'%s','%s',%d,'%s','%s')",
			            userInf.id,userInf.nickname,userInf.sex,userInf.age,userInf.address,userInf.password);
			try
			{
				if(dlg->m_pSet->IsOpen())
					dlg->m_pSet->Close();
				if ( ! dlg->m_pSet->IsOpen()) // if the recordset isn't already open..
					dlg->m_pSet->Open(CRecordset::dynaset,"select * from userinfo"); 
				dlg->m_pSet->m_pDatabase->ExecuteSQL(strSQL);
				dlg->m_pSet->Close();
				nRetVal = REGT_SUCCESS;

			}
			catch(CDBException *e)
			{
				PrintSystemError(e->m_strError);
				nRetVal = REGT_FAIL_BECAUSE_DBWRITE; //注册写数据库失败
			}
		}
		
		
		//回复2条信息
		//第一条发送修改成功与否的命令
		memset(buff,0,sizeof(buff));
		sprintf(buff,"%d",nRetVal);		
		if(send(pSI->s,buff,sizeof(buff),0) == SOCKET_ERROR)
		{
			closesocket(pSI->s);
			PrintSystemError("REGT send id命令出错");
			return 1;
		}

		//如果注册成功,再发1个注册成功的号码
		if(nRetVal == REGT_SUCCESS)
		{
			memset(buff,0,sizeof(buff));
			sprintf(buff,"%d",userInf.id);
			if(send(pSI->s,buff,sizeof(buff),0) == SOCKET_ERROR)
			{
				closesocket(pSI->s);
				PrintSystemError("REGT send命令出错");
				return 1;
			}
		}


		return nRetVal;
}

int DealCommand( LPSOCKET_INF pSI )
{
	int nRetVal = 0;
	char  szCmd[MAX_REQ_LEN]; 
	CString strSQL;
	CNetMsgServerDlg *dlg=(CNetMsgServerDlg*) AfxGetApp()->GetMainWnd();
	char buff[MAX_BUFF_SIZE];

	strcpy(szCmd, pSI->buffRecv);
	if( strtok( szCmd," \t\n") == NULL ) return -1;

	//发送在线用户列表
	if( strstr(szCmd,"LIST") )
	{

		send(pSI->s, (char *)g_onlineUser, sizeof(g_onlineUser),0);

	}
	
	//发送查询到的该用户信息 例如:"GINF 1000\t\n"就是get用户1000的信息
	if(strstr(szCmd,"GINF"))
	{
		USER_INF userInf;
		char strId[20];
		long userID =0;
		
		memset(strId,0,sizeof(strId));
		sprintf(strId,"%s",szCmd+strlen("GINF")+1);
		userID = atoi(strId);
		
		strSQL.Empty();
		strSQL.Format("Select * FROM userinfo WHERE id = %d",userID);
		
		try{

			//如果记录集已打开,则关闭它
			if(dlg->m_pSet->IsOpen())
				dlg->m_pSet->Close();
			//打开记录集
			dlg->m_pSet->Open(CRecordset::dynaset,strSQL);
	
			if(!(dlg->m_pSet->IsEOF()))
			{			
				CString strNickname,strSex,strAge,strAddress,strPassword;
				dlg->m_pSet->GetFieldValue("nickname",strNickname);
				dlg->m_pSet->GetFieldValue("sex",strSex);
				dlg->m_pSet->GetFieldValue("age",strAge);
				dlg->m_pSet->GetFieldValue("address",strAddress);
				dlg->m_pSet->GetFieldValue("password",strPassword);

				userInf.id = userID;
				strcpy(userInf.nickname,strNickname);
				strcpy(userInf.sex,strSex);
				userInf.age = atoi(strAge);
				strcpy(userInf.address,strAddress);
				strcpy(userInf.password,strPassword);
			}
			dlg->m_pSet->Close();
		}
		catch(CDBException *e)
		{
			PrintSystemError(e->m_strError);
		}

		send(pSI->s, (char *)&userInf, sizeof(userInf),0);
		
	}

	//修改该用户信息 例如:"UINF 1000\t\n"就是update用户1000的信息
	if(strstr(szCmd,"UINF"))
	{
		USER_INF userInf;
		char strId[20];
		long userID =0;

		memset(strId,0,sizeof(strId));
		sprintf(strId,"%s",szCmd+strlen("UINF")+1);
		userID = atoi(strId);
		//接受修改后信息
		if(recv(pSI->s,(char *)&userInf,sizeof(userInf),0) == SOCKET_ERROR)
		{
			closesocket(pSI->s);
			PrintSystemError("UINF命令出错");
			return 1;
		}

		//修改数据库记录
		strSQL = _T("");
		strSQL.Format("update userinfo set password='%s',nickname='%s',sex='%s',age=%d,address='%s' where id =%ld",
					userInf.password,userInf.nickname,userInf.sex,userInf.age,userInf.address,userID);

		try
		{
			if(dlg->m_pSet->IsOpen())
				dlg->m_pSet->Close();

			if ( ! dlg->m_pSet->IsOpen()) // if the recordset isn't already open..
				dlg->m_pSet->Open(CRecordset::dynaset,"select * from userinfo"); 

			dlg->m_pSet->m_pDatabase->ExecuteSQL(strSQL);
			dlg->m_pSet->Close();
			nRetVal = UPDATE_SUCCESS;

		}
		catch(CDBException *e)
		{
			PrintSystemError(e->m_strError);
			nRetVal = UPDATE_FAIL;
		}
		
		memset(buff,0,sizeof(buff));
		sprintf(buff,"%d",nRetVal);

		//发送修改成功与否的命令
		if(send(pSI->s,buff,sizeof(buff),0) == SOCKET_ERROR)
		{
			closesocket(pSI->s);
			PrintSystemError("UINF命令出错");
			return 1;
		}

		//如果修改成功,还需要需要更新在线列表
		if(nRetVal == UPDATE_SUCCESS)
		{
			for(DWORD i=0;i<g_ouIndex;i++)
			{
				if(g_onlineUser[i].id == userID)
				{
					memset(g_onlineUser[i].nickname,0,sizeof(g_onlineUser[i].nickname));
					strcpy(g_onlineUser[i].nickname,userInf.nickname);
					break;
				}
			}

		}

	}
	return 0;

}

void PrintSystemError(CString str)
{
	char strSystemError[40];
	CNetMsgServerDlg *dlg=(CNetMsgServerDlg*) AfxGetApp()->GetMainWnd();

	memset(strSystemError,0,sizeof(strSystemError));
	sprintf(strSystemError,"系统:%s",str);
	dlg->m_list.InsertString(g_dwListCount++, strSystemError);
	dlg->m_list.SetTopIndex(g_dwListCount-1);
}

void CNetMsgServerDlg::OnServerStop() 
{
	exit(0);
}



void CNetMsgServerDlg::OnClose() 
{
	//如果记录集已打开,则关闭它
	if(m_pSet->IsOpen())
		m_pSet->Close();	
	WSACleanup(); 
	CDialog::OnClose();
}

void CNetMsgServerDlg::OnTrayRestore() 
{
	ShowWindow(SW_RESTORE);

}

void CNetMsgServerDlg::OnTrayExit() 
{
	m_trayIcon.RemoveIcon();
	exit(0);	
}

LRESULT CNetMsgServerDlg::OnTrayNotification(WPARAM wParam, LPARAM lParam)
{
	return m_trayIcon.OnTrayNotification(wParam,lParam);
}



void CNetMsgServerDlg::OnAboutnetmsg() 
{
	CAboutDlg dlgAbout;
	dlgAbout.DoModal();		
}

⌨️ 快捷键说明

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