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

📄 tcpserver.cpp

📁 《 MFC 编程技巧与范例详解 》〔曾凡锋
💻 CPP
字号:
// TCPServer.cpp: implementation of the CTCPServer class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "MTServer.h"
#include "TCPServer.h"

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

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
const char* Command[] =
{
"AUTH",
"FILE",
"QUIT",
"#Ready",
"#LOGIN OK",
"!LOGIN FAIL",
"!NOT LOGIN",
"#SEND OK",
"!NO FILE",
"!ERROR CMD",
};

SOCKET CTCPServer::m_server = NULL;
UINT CTCPServer::m_nPort = TCP_PORT;
CString CTCPServer::m_sPassword = "ncut";
BOOL CTCPServer::m_bStart = FALSE;
CStringList CTCPServer::m_lstClient;
my_callback CTCPServer::m_callback = NULL;
CDialog* CTCPServer::m_pDlg = NULL;

CTCPServer::CTCPServer()
{

}

CTCPServer::~CTCPServer()
{

}

void CTCPServer::Start()
{
	m_bStart = TRUE;
	AfxBeginThread(MTServerThread,0);
}

void CTCPServer::Stop()
{
	m_bStart = FALSE;
	closesocket(m_server);
	WSACleanup();

	m_lstClient.RemoveAll();
}

UINT CTCPServer::MTServerThread(LPVOID pParam)
{		
	WSADATA wsaData;
	sockaddr_in local;
	int wsaret=WSAStartup(0x101,&wsaData); // 初始化Winsock动态库
	if(wsaret!=0)
	{
		return 0;
	}
	local.sin_family=AF_INET;
	local.sin_addr.s_addr=INADDR_ANY;
	local.sin_port=htons((u_short)m_nPort);
	m_server=socket(AF_INET,SOCK_STREAM,0);
	if(m_server==INVALID_SOCKET)
	{
		return 0;
	}
	if(bind(m_server,(sockaddr*)&local,sizeof(local))!=0) // 绑定端口
	{
		return 0;
	}
	if(listen(m_server,10)!=0) // 侦听端口
	{
		return 0;
	}

	SOCKET client;
	sockaddr_in from;
	int fromlen = sizeof(from);

	while(m_bStart)
	{
		client=accept(m_server,(struct sockaddr*)&from,&fromlen); // 获得客户端连接请求

		SocketData data;
		data.socket = client;
		data.from = from;

		AfxBeginThread(ClientThread,(LPVOID)&data);	 // 启动处理客户端消息线程
	}	

	return 0;
}

UINT CTCPServer::ClientThread(LPVOID pParam)
{
	char buff[BUFFER_SIZE];
	CString cmd;
	CString params;
	int n;
	int x;
	BOOL auth=false;

	SocketData* data = (SocketData*)pParam;
	SOCKET client = (SOCKET)data->socket;

	char *ip = inet_ntoa(data->from.sin_addr);
	CString s;
	s.Format("%s", ip);
	m_lstClient.AddTail(s);

	if( m_callback && m_pDlg )
	{
		m_callback(m_pDlg, s, 1);	
	}

	strcpy(buff,Command[READY]);
	send(client,buff,strlen(buff),0);
	while(true)
	{
		n = recv(client,buff,BUFFER_SIZE,0);
		if(n==SOCKET_ERROR )			
			break;
		buff[n]=0;
		if(ParseCmd(buff,cmd,params))
		{
			if(cmd==Command[CMD_QUIT])
				break;
			if(cmd=="AUTH")
			{
				if(params==m_sPassword)
				{
					auth=true;
					strcpy(buff,Command[LOGIN_OK]);
				}
				else
				{
					strcpy(buff,Command[LOGIN_FAIL]);
				}
				send(client,buff,strlen(buff),0);
			}
			if(cmd=="FILE")
			{
				if(auth)
				{
					if(SendFile(client,params))
						sprintf(buff,"%s %s",Command[SEND_OK], params);
					else
						sprintf(buff,"%s %s",Command[NO_FILE], params);
					x=send(client,buff,strlen(buff),0);					
				}
				else
				{
					strcpy(buff,Command[NOT_LOGIN]);
					send(client,buff,strlen(buff),0);
				}
			}
		}
		else
		{
			strcpy(buff,Command[ERROR_CMD]);
			send(client,buff,strlen(buff),0);
		}
	}		

	closesocket(client);

	if( m_callback && m_pDlg )
	{
		m_callback(m_pDlg, s, 2);	
	}

	POSITION pos = m_lstClient.Find(s);
	if( pos )
	{
		m_lstClient.RemoveAt(pos);
	}
	return 0;
}

BOOL CTCPServer::ParseCmd(char *str, CString& cmd, CString& params)
{
	int n;
	CString tmp=str;	
	tmp.TrimLeft();
	tmp.TrimRight();	
	if((n = tmp.Find(' ')) == -1)
	{
		tmp.MakeUpper();
		if(tmp != Command[CMD_QUIT])
			return false;
		cmd = tmp;
		return true;
	}		
	cmd = tmp.Left(n);
	params = tmp.Mid(n+1);
	cmd.MakeUpper();
	if((cmd != Command[CMD_AUTH]) && (cmd != Command[CMD_FILE]))
		return false;
	return true;
}

BOOL CTCPServer::SendFile(SOCKET s, CString fname)
{	
	CFile f;
	BOOL p = f.Open(fname,CFile::modeRead);	
	char buff[BUFFER_SIZE];
	int y;
	int x;
	if(!p)
		return false;
	while(true)
	{		
		y = f.Read(buff,BUFFER_SIZE);
		x = send(s,buff,y,0);		
		if(y < BUFFER_SIZE)
		{
			f.Close();
			break;
		}			
	}	

	return true;
}

⌨️ 快捷键说明

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