蜗牛的家
男儿当自强
posts - 48,  comments - 21,  trackbacks - 0
#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
  4CHpServer::CHpServer(void)
  5{
  6    WSADATA wsaData;
  7    WSAStartup(MAKEWORD(2,2), &wsaData);
  8
  9    m_lsSocket = INVALID_SOCKET;
 10}

 11
 12CHpServer::~CHpServer(void)
 13{
 14    WSACleanup();
 15}

 16
 17BOOL 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
 50void CHpServer::StopServer()
 51{
 52    if (m_lsSocket != INVALID_SOCKET)
 53    {
 54        closesocket(m_lsSocket);
 55        m_lsSocket = INVALID_SOCKET;
 56    }

 57}

 58
 59DWORD 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
 95DWORD 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
124BOOL 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
169int 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
187void 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
222BOOL 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 黑色天使 阅读(310) 评论(0)  编辑 收藏 引用 所属分类: 网络开发

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理



<2008年12月>
30123456
78910111213
14151617181920
21222324252627
28293031123
45678910

常用链接

留言簿(2)

随笔分类

随笔档案

文章档案

搜索

  •  

最新评论

阅读排行榜

评论排行榜