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

📄 serversocket.cpp

📁 点歌系统
💻 CPP
字号:
// ServerSocket.cpp: implementation of the CServerSocket class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "songserver.h"
#include "ServerSocket.h"

#include "MainFrm.h"
#include "songserverView.h"
#include "SonglistView.h"

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

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

/*///////////////////////////////////////////////
当有客户连接时,客户将自己的计算机名发到服务器端,
以确定不同的用户登录

收到客户发的计算机名后,若当前在线的客户已达到5个
则向客户发送close,要使客户关闭套接字,稍后再连接。

若当前在线的客户少于五个,则向客户发送ok,表示连接
成功。

连接成功后,向两个VIEW类发ADDUSER消息,以更新用户
信息及用户点歌信息
*////////////////////////////////////////////////

int CServerSocket::m_nClientIndex = 0;
int CServerSocket::m_nClientOnline = 0;
CString CServerSocket::m_strClientname[m_nClientNum] = {""};
SOCKET CServerSocket::m_listenSocket = NULL;
SOCKET CServerSocket::m_clientSocket[m_nClientNum] = {NULL};

CServerSocket::CServerSocket()
{
	m_hSocket = NULL;
}

CServerSocket::~CServerSocket()
{

}

void CServerSocket::BeginServer()
{
	if( m_hSocket != NULL)
		return;

	m_hSocket = CreateThread(NULL, NULL, ServerThread, NULL, NULL, NULL);
}

void CServerSocket::StopServer()
{
	for(int i = 0; i < m_nClientNum; i++)
	{
		if(m_clientSocket[i] == NULL)
			continue;
		closesocket(m_clientSocket[i]);
	}
 
	m_nClientOnline = 0;
	TerminateThread(m_hSocket, 0);
    CloseHandle(m_hSocket);
 	WSACleanup();
}

DWORD CServerSocket::ServerThread(LPVOID lParam)
{
	int ret(0);
 	WSADATA wsaData;

	ret = WSAStartup(MAKEWORD(2, 2), &wsaData);	 
	if (ret != 0) 
	{
		return 1;
	}
	m_listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (m_listenSocket == INVALID_SOCKET)
	{
		WSACleanup();
		return 1;
	}	
	
	struct sockaddr_in sockaddr;
	sockaddr.sin_family = AF_INET;
	sockaddr.sin_port = htons(8888);
	sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);

	ret = bind(m_listenSocket,(struct sockaddr *)&sockaddr,sizeof(sockaddr));
	if (ret == SOCKET_ERROR)
	{
		closesocket(m_listenSocket);
		WSACleanup();
		return 1;
	}
	ret = listen(m_listenSocket, m_nClientNum);
	if(ret == SOCKET_ERROR)
	{
		closesocket(m_listenSocket);
		WSACleanup();
		return 1;
	}

	struct sockaddr_in clientSockaddr;
	int addrlen=sizeof(clientSockaddr);

	//得到主框架类的指针
	CMainFrame* pMainWnd = (CMainFrame*)AfxGetMainWnd();
	pMainWnd->m_WndSplitter.SetActivePane(0, 1, pMainWnd);
	CSongserverView* pListView = (CSongserverView*)(pMainWnd->GetActiveView());
	
//	CSonglistView TreeView;

	while(1)
	{
 		SOCKET clientSocket = INVALID_SOCKET;
		clientSocket = accept(m_listenSocket, (struct sockaddr *)&clientSockaddr, &addrlen);
		if( clientSocket == INVALID_SOCKET)
		{
 			closesocket(m_listenSocket);
			return 1;
		}

		char rcvbuf[256] = {0};
		ret = recv(clientSocket, rcvbuf, sizeof(rcvbuf), 0);
		if(ret == SOCKET_ERROR)
		{
			AfxMessageBox("接收消息出错.");
 			return 1;
		}
		rcvbuf[ret] = 0;		

		if( m_nClientOnline == m_nClientNum )
		{
			char szmsg[] = "close";
			send(clientSocket, szmsg, sizeof(szmsg), 0);
			Sleep(100);
			closesocket(clientSocket);
 			continue;
		}

		char szmsg[] = "ok";
		send(clientSocket, szmsg, sizeof(szmsg), 0);
		for(int i = 0; i < m_nClientNum; i++)
		{
			if(m_clientSocket[i] == NULL)
			{
				m_nClientIndex = i;
				break;
			}
		}

		switch(m_nClientIndex)
		{
		case 0:
			CreateThread(NULL, NULL, ClientThread_1, pListView, NULL, NULL);
			break;
		case 1:
			CreateThread(NULL, NULL, ClientThread_2, pListView, NULL, NULL);
			break;
		case 2:
			CreateThread(NULL, NULL, ClientThread_3, pListView, NULL, NULL);
			break;
		case 3:
			CreateThread(NULL, NULL, ClientThread_4, pListView, NULL, NULL);
			break;
		case 4:
			CreateThread(NULL, NULL, ClientThread_5, pListView, NULL, NULL);
			break;
		}
		
		m_clientSocket[m_nClientIndex] = clientSocket;
		++m_nClientOnline;
		m_strClientname[m_nClientIndex] = rcvbuf;

	//	TreeView.OnAddUser(m_nClientIndex, rcvbuf);
		if( pListView != NULL )
			pListView->SendMessage(WM_ADDUSER, (WPARAM)rcvbuf);
	}

	return 0;
}

int CServerSocket::GetOnlineClientNum()
{
	return m_nClientOnline;
}

CString* CServerSocket::GetClientName()
{
 	return m_strClientname;
}

DWORD CServerSocket::ClientThread_1(LPVOID lParam)
{
	int ret = 0;
	char rcvbuf[256] = {""};
	while(1)
	{
		ret = recv(m_clientSocket[0], rcvbuf, sizeof(rcvbuf), 0);
		if(ret == SOCKET_ERROR)
		{
			closesocket(m_clientSocket[0]);
			m_clientSocket[0] = NULL;
			return 1;
		}
		rcvbuf[ret] = 0;

		if( !SendMsg(0, rcvbuf, lParam) )
			return 1;
	}
	
 	return 0;
}

DWORD CServerSocket::ClientThread_2(LPVOID lParam)
{
	int ret = 0;
	char rcvbuf[256] = {""};
	while(1)
	{
		ret = recv(m_clientSocket[1], rcvbuf, sizeof(rcvbuf), 0);
		if(ret == SOCKET_ERROR)
		{
			closesocket(m_clientSocket[1]);
			m_clientSocket[1] = NULL;
			return 1;
		}
		rcvbuf[ret] = 0;

		if( !SendMsg(1, rcvbuf, lParam) )
			return 1;
	}
	return 0;
}

DWORD CServerSocket::ClientThread_3(LPVOID lParam)
{
	int ret = 0;
	char rcvbuf[256] = {""};
	while(1)
	{
		ret = recv(m_clientSocket[2], rcvbuf, sizeof(rcvbuf), 0);
		if(ret == SOCKET_ERROR)
		{
			closesocket(m_clientSocket[2]);
			m_clientSocket[2] = NULL;
			return 1;
		}
		rcvbuf[ret] = 0;

		if( !SendMsg(2, rcvbuf, lParam) )
			return 1;
	}

	return 0;
}

DWORD CServerSocket::ClientThread_4(LPVOID lParam)
{
	int ret = 0;
	char rcvbuf[256] = {""};
	while(1)
	{
		ret = recv(m_clientSocket[3], rcvbuf, sizeof(rcvbuf), 0);
		if(ret == SOCKET_ERROR)
		{
			closesocket(m_clientSocket[3]);
			m_clientSocket[3] = NULL;
			return 1;
		}
		rcvbuf[ret] = 0;

		if( !SendMsg(3, rcvbuf, lParam) )
			return 1;
	}

	return 0;
}

DWORD CServerSocket::ClientThread_5(LPVOID lParam)
{
	int ret = 0;
	char rcvbuf[256] = {""};
	while(1)
	{
		ret = recv(m_clientSocket[4], rcvbuf, sizeof(rcvbuf), 0);
		if(ret == SOCKET_ERROR)
		{
			closesocket(m_clientSocket[4]);
			m_clientSocket[0] = NULL;
			return 1;
		}
		rcvbuf[ret] = 0;

		if( !SendMsg(4, rcvbuf, lParam) )
			return 1;
	}

	return 0;
}

////////////////////////////////////////////////////////////////////
/*函数功能: 判断客户端发来的消息是退出还是重新从数据库得到已点歌曲
//参数说明: nIndex: 客户索引
//          szbuf:  从客户端接收到的数据    
                    LoadAgain: 重新从数据库得到已点歌曲
                    select: 查询已用时间和应交费用
					quit: 退出程序
//          lParam: CSongserverView的指针 */
BOOL CServerSocket::SendMsg(int nIndex, char* szbuf, LPVOID lParam)
{
	CTime time;
 	time = CTime::GetCurrentTime();

	if( !strcmp(szbuf, "LoadAgain") )//登录
	{
		CSonglistView::SetLoadAgain(nIndex);
	}
	else if( !strcmp(szbuf, "select") )//查询时间和费用
	{
		//发送已用时间和应付费用到客户端
		CString strmsg("");
		CString strtmp;
		CString strlen;

		strtmp = ((CSongserverView*)lParam)->GetUsedTime(nIndex);
		strlen.Format("%d", strtmp.GetLength());
		strmsg += strlen;
 		strmsg += strtmp;
        
 		strtmp = ((CSongserverView*)lParam)->GetPayForMoney(nIndex);
		strlen.Format("%d", strtmp.GetLength());
		strmsg += strlen;
 		strmsg += strtmp;

   		send(m_clientSocket[nIndex], strmsg.GetBuffer(0), strmsg.GetLength(), 0);
	}
	else if( !strcmp(szbuf, "reconnect") )//结帐后再连接服务器
	{
		CString strmsg;
		strmsg.Format("%s房间要求重新记费,\n是否同意?", m_strClientname[nIndex]);
		int ret = AfxMessageBox(strmsg, MB_ICONINFORMATION | MB_YESNO); 
		if( ret == 6 )
			send(m_clientSocket[nIndex], "ok", 3, 0);
		else
			send(m_clientSocket[nIndex], "no", 3, 0);
	}
	else if( !strcmp(szbuf, "payment") )//结帐
	{
		char* szonline = "否";
 		((CSongserverView*)lParam)->SendMessage(WM_ADDUSER, (WPARAM)m_strClientname[nIndex].GetBuffer(0), (LPARAM)szonline);
        m_nClientOnline--;
 	}
	else if( !strcmp(szbuf, "quit") )//退出
	{
		char* szonline = "否";
 		((CSongserverView*)lParam)->SendMessage(WM_ADDUSER, (WPARAM)m_strClientname[nIndex].GetBuffer(0), (LPARAM)szonline);
        m_nClientOnline--;

		//发送已用时间和应付费用到客户端
		CString strmsg("");
		CString strtmp;
		CString strlen;

		strtmp = ((CSongserverView*)lParam)->GetUsedTime(nIndex);
		strlen.Format("%d", strtmp.GetLength());
		strmsg += strlen;
 		strmsg += strtmp;
        
 		strtmp = ((CSongserverView*)lParam)->GetPayForMoney(nIndex);
		strlen.Format("%d", strtmp.GetLength());
		strmsg += strlen;
 		strmsg += strtmp;

 		send(m_clientSocket[nIndex], strmsg.GetBuffer(0), strmsg.GetLength(), 0);
	
		closesocket(m_clientSocket[nIndex]);
		m_clientSocket[nIndex] = NULL;
	}

	return true;
}

⌨️ 快捷键说明

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