📄 tcpserver.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 + -