Web服务器继续。。。
1.接下来具体实现Web服务,添加类成员变量:
类成员变量 | 类型 |
---|---|
m_hExit | HANDLE |
m_listenSocket | SOCKET |
m_pListenThread | CWinThread* |
None | static HANDLE |
ClientNum | static UINT |
m_critSect | static CCriticalSection |
m_typeMap | map<CString, char*> |
其中,关于map用法:参考链接
map<键,值>可以理解为:
map[键] = 值
使用时:
map<CString, char*>::iterator it
输出时:
it.first输出键, it.second输出值
通常结合it.find(键)查找值
2.添加数据结构体:用于保存client信息的结构体
typedef struct REQUEST
{
HANDLE hExit;
SOCKET Socket;
int nMethod;
HANDLE hFile;
char szFileName[254];
char postfix[10];
char StatuCodeReason[100];
void *pWebServerDlg;
}REQUEST, *PREQUEST;
Web服务流程图:
1.基于上面流程图,实现StartWebServer()以及StopWebServer()
void CWebServerDlg::StartWebServer()
{
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);
m_hExit = CreateEvent(NULL, TRUE, FALSE, NULL);
//创建监听套接字
m_listenSocket = socket(AF_INET, SOCK_STREAM, 0);
BYTE nFild[4];
CString sIP;
LocalIP.GetAddress(nFild[0], nFild[1], nFild[2], nFild[3]);
sIP.Format("%d.%d.%d.%d", nFild[0], nFild[1], nFild[2], nFild[3]);
//服务器地址
sockaddr_in sockAddr;
sockAddr.sin_family = AF_INET;
sockAddr.sin_addr.S_un.S_addr = inet_addr(sIP);
sockAddr.sin_port = htons(m_nPort);
//初始化content-type和文件后缀对应关系的map
CreateTypeMap();
//绑定套接字
bind(m_listenSocket, (sockaddr*)&sockAddr, sizeof(sockAddr));
//开始监听
listen(m_listenSocket, 5);
//创建监听线程,接收客户连接要求
m_pListenThread = AfxBeginThread(ListenThread, this);
//显示服务器启动信息
CString *pStr = new CString;
*pStr = "Start WebServer Succeed";
SendMessage(LOG_MSG, (UINT)pStr, NULL);
char hostname[255];
gethostname(hostname, sizeof(hostname));
CString *pStr1 = new CString;
pStr1->Format("%s", hostname);
*pStr1 = *pStr1 + "[" + sIP;
CString strTmp;
strTmp.Format(":%d]", m_nPort);
*pStr1 += strTmp;
SendMessage(LOG_MSG, (UINT)pStr1, NULL);
}
void CWebServerDlg::StopWebServer()
{
SetEvent(m_hExit);
closesocket(m_listenSocket);
int nRet = WaitForSingleObject((HANDLE)m_pListenThread, 10000);
if (nRet == WAIT_TIMEOUT)
{
CString *pStr = new CString;
*pStr = "TIMEOUT waiting for ListenThread";
SendMessage(LOG_MSG, (UINT)pStr, NULL);
}
CloseHandle(m_hExit);
CString *pStr1 = new CString;
*pStr1 = "WebServer Stopped";
SendMessage(LOG_MSG, (UINT)pStr1, NULL);
}
分析:其中StopWebServer()里面的句柄hExit使用,参考链接
2.效果展示:以下是实现了创建监听套接字和关闭监听套接字的过程