#pragma once

#include <WinSock2.h>


class CHpServer


{
public:
CHpServer(void);
virtual ~CHpServer(void);

BOOL StartSever(CString RootDir, u_short port);
void StopServer();

protected:
BOOL RecvRequest(SOCKET sk, HANDLE hExit, PCHAR pBuf, DWORD bufSize);
int ParseRequest(PCHAR lpBuf, CString &fileName);
void SendFile(SOCKET sk, HANDLE hExit, CString filePath);
BOOL SendBuffer(SOCKET sk, HANDLE hExit, PCHAR pBuf, DWORD bufSize);


static DWORD WINAPI ListenThread(PVOID lParam);
static DWORD WINAPI ClientThread(PVOID lParam);

private:
SOCKET m_lsSocket;
CString m_RootDir;
};


typedef struct stg_Req


{
SOCKET skClient;
HANDLE hExitEvent;
CString rootDir;
CHpServer* pThis;
}REQUEST, *LPReq;
1
#include "StdAfx.h"
2
#include "HpServer.h"
3
4
CHpServer::CHpServer(void)
5

{
6
WSADATA wsaData;
7
WSAStartup(MAKEWORD(2,2), &wsaData);
8
9
m_lsSocket = INVALID_SOCKET;
10
}
11
12
CHpServer::~CHpServer(void)
13

{
14
WSACleanup();
15
}
16
17
BOOL CHpServer::StartSever(CString RootDir, u_short port)
18

{
19
if (strcmp(RootDir, _T("")) == 0)
20
return FALSE;
21
22
m_RootDir = RootDir;
23
m_lsSocket = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED);
24
SOCKADDR_IN sk_Addr;
25
26
sk_Addr.sin_family = AF_INET;
27
sk_Addr.sin_port = htons(port);
28
sk_Addr.sin_addr.s_addr = ADDR_ANY;
29
30
if (bind(m_lsSocket, (LPSOCKADDR)&sk_Addr, sizeof(struct sockaddr)) == SOCKET_ERROR)
31
{
32
closesocket(m_lsSocket);
33
return FALSE;
34
}
35
if (listen(m_lsSocket, 10) == SOCKET_ERROR)
36
{
37
closesocket(m_lsSocket);
38
return FALSE;
39
}
40
41
DWORD dwThreadID;
42
HANDLE hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ListenThread, this, NULL, &dwThreadID);
43
if (hThread == INVALID_HANDLE_VALUE)
44
return FALSE;
45
CloseHandle(hThread);
46
47
return TRUE;
48
}
49
50
void CHpServer::StopServer()
51

{
52
if (m_lsSocket != INVALID_SOCKET)
53
{
54
closesocket(m_lsSocket);
55
m_lsSocket = INVALID_SOCKET;
56
}
57
}
58
59
DWORD WINAPI CHpServer::ListenThread(PVOID lParam)
60

{
61
CHpServer* pThis = (CHpServer*)lParam;
62
HANDLE hExitEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
63
64
while (TRUE)
65
{
66
SOCKADDR_IN sk_Addr;
67
int nSize = sizeof(sk_Addr);
68
SOCKET skClient = accept(pThis->m_lsSocket, (PSOCKADDR)&sk_Addr, &nSize);
69
70
if (skClient == INVALID_SOCKET)
71
break;
72
73
LPReq lpReq = new REQUEST;
74
lpReq->skClient = skClient;
75
lpReq->hExitEvent = hExitEvent;
76
lpReq->rootDir = pThis->m_RootDir;
77
78
DWORD dwThreadID;
79
HANDLE hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ClientThread, lpReq, NULL, &dwThreadID);
80
if (hThread == INVALID_HANDLE_VALUE)
81
{
82
closesocket(skClient);
83
delete lpReq;
84
continue;
85
}
86
CloseHandle(hThread);
87
}
88
SetEvent(hExitEvent);
89
Sleep(1000); //等待服务线程退出
90
CloseHandle(hExitEvent);
91
92
return 1;
93
}
94
95
DWORD WINAPI CHpServer::ClientThread(PVOID lParam)
96

{
97
LPReq lpReq = (LPReq)lParam;
98
99
CHAR buf[1024];
100
101
if (!lpReq->pThis->RecvRequest(lpReq->skClient, lpReq->hExitEvent, buf, 1024))
102
{
103
closesocket(lpReq->skClient);
104
delete lpReq;
105
return 1;
106
}
107
CString filePath = lpReq->rootDir;
108
109
if (!lpReq->pThis->ParseRequest(buf, filePath))
110
{
111
closesocket(lpReq->skClient);
112
delete lpReq;
113
return 1;
114
}
115
116
lpReq->pThis->SendFile(lpReq->skClient, lpReq->hExitEvent, filePath);
117
118
closesocket(lpReq->skClient);
119
delete lpReq;
120
return 1;
121
}
122
123
124
BOOL CHpServer::RecvRequest(SOCKET sk, HANDLE hExit, PCHAR pBuf, DWORD bufSize)
125

{
126
memset(pBuf, 0, bufSize);
127
128
WSABUF wsaBuf;
129
WSAOVERLAPPED wsaOver;
130
131
wsaBuf.buf = pBuf;
132
wsaBuf.len = bufSize;
133
wsaOver.hEvent = WSACreateEvent();
134
135
DWORD dwRecvSize, dwFlags = 0;
136
int nRet = WSARecv(sk, &wsaBuf, 1, &dwRecvSize, &dwFlags, &wsaOver, NULL);
137
138
if (nRet != 0 && WSAGetLastError() != WSA_IO_PENDING)
139
{
140
CloseHandle(wsaOver.hEvent);
141
return FALSE;
142
}
143
144
if (nRet != 0)
145
{
146
HANDLE hEvents[2] =
{wsaOver.hEvent, hExit};
147
148
if ( WaitForMultipleObjects(2, hEvents, FALSE, INFINITE) != 0)
149
{
150
CloseHandle(wsaOver.hEvent);
151
return FALSE;
152
}
153
154
if (!WSAGetOverlappedResult(sk,
155
&wsaOver,
156
&dwRecvSize,
157
FALSE,
158
&dwFlags))
159
{
160
CloseHandle(wsaOver.hEvent);
161
return FALSE;
162
}
163
}
164
165
CloseHandle(wsaOver.hEvent);
166
return TRUE;
167
}
168
169
int CHpServer::ParseRequest(PCHAR lpBuf, CString &filePath)
170

{
171
PCHAR cpNtToken;
172
PCHAR cpToken = strtok_s(lpBuf, _T(" \n"), &cpNtToken);
173
174
if (strcmp(cpToken, _T("GET")) != 0)
175
return 0;
176
177
cpToken = strtok_s(NULL, _T(" \n"), &cpNtToken);
178
if (cpToken == NULL)
179
return 0;
180
181
filePath.Format(_T("%s%s"),filePath, cpToken);
182
183
return 1;
184
}
185
186
187
void CHpServer::SendFile(SOCKET sk, HANDLE hExit, CString fileName)
188

{
189
HANDLE hFile = CreateFile(fileName,
190
GENERIC_READ,
191
FILE_SHARE_READ,
192
NULL,
193
OPEN_EXISTING,
194
FILE_ATTRIBUTE_NORMAL,
195
NULL);
196
197
if (hFile == INVALID_HANDLE_VALUE)
198
return;
199
200
DWORD dwSize = GetFileSize(hFile,NULL);
201
TCHAR pResponseHeader[1024];
202
sprintf_s(pResponseHeader, 1024,
203
_T("HTTP/1.1 200 OK\r\nAccept-Ranges: bytes\r\nContent-Length: "\
204
"%d\r\nConnection: Keep-Alive\r\nContent-Type: text/plain\r\n\r\n"),
205
dwSize);
206
SendBuffer(sk,hExit,pResponseHeader,strlen(pResponseHeader));
207
208
static CHAR buf[1024];
209
while (WaitForSingleObject(hExit, 0) == WAIT_TIMEOUT)
210
{
211
DWORD dwSize;
212
if (!ReadFile(hFile, buf, 1024, &dwSize, NULL) || dwSize == 0)
213
break;
214
215
if (!SendBuffer(sk, hExit, buf, dwSize))
216
break;
217
}
218
219
CloseHandle(hFile);
220
}
221
222
BOOL CHpServer::SendBuffer(SOCKET sk, HANDLE hExit, PCHAR pBuf, DWORD bufSize)
223

{
224
WSABUF wsaBuf;
225
WSAOVERLAPPED wsaOver;
226
227
wsaBuf.buf = pBuf;
228
wsaBuf.len = bufSize;
229
wsaOver.hEvent = WSACreateEvent();
230
231
DWORD dwRecv, dwFlags;
232
int nRet = WSASend(sk, &wsaBuf, 1, &dwRecv, 0, &wsaOver, NULL);
233
if (nRet != 0 && WSAGetLastError() != WSA_IO_PENDING)
234
return FALSE;
235
236
if (nRet != 0)
237
{
238
HANDLE hEvents[2] =
{wsaOver.hEvent, hExit};
239
240
if (WaitForMultipleObjects(2, hEvents, FALSE, INFINITE) != 0)
241
{
242
CloseHandle(wsaOver.hEvent);
243
return FALSE;
244
}
245
246
if (!WSAGetOverlappedResult(sk, &wsaOver, &dwRecv, FALSE, &dwFlags))
247
{
248
CloseHandle(wsaOver.hEvent);
249
return FALSE;
250
}
251
}
252
253
CloseHandle(wsaOver.hEvent);
254
return TRUE;
255
}
256
257
posted on 2008-12-30 16:51
黑色天使 阅读(330)
评论(0) 编辑 收藏 引用 所属分类:
网络开发