#include <afx.h> //为了使用CFile 类:1、添加#include <afx.h>;2、工程中设置MFC的DLL
#include <stdio.h>
#include <iostream.h>
#include <winsock2.h>
#include <sys/stat.h>
#include <fstream.h>
#pragma comment(lib, "ws2_32")
/*******************
//创建服务器套接字
*******************/
SOCKET createServerSocket()
{
WSADATA ws;
WSAStartup(MAKEWORD(1,1), &ws);
SOCKADDR_IN sockaddr;
sockaddr.sin_family = AF_INET;
sockaddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY); //inet_addr("127.0.0.1");
sockaddr.sin_port = htons(6000);
SOCKET serverSocket = socket(AF_INET, SOCK_STREAM, 0);
if (serverSocket == INVALID_SOCKET)
{
cout<<"创建服务器套接字失败!"<<endl;
return WSAGetLastError();
}
int err = bind(serverSocket, (SOCKADDR*)&sockaddr, sizeof(SOCKADDR));
if (err == SOCKET_ERROR)
{
cout<<"绑定失败!"<<endl;
return WSAGetLastError();
}
::listen(serverSocket, 2);
return serverSocket;
}
/*****************************
//查找服务器根目录下的文件清单
******************************/
void findAllFile(CString path, CString* fileNames, CString serverIP)
{
CString subPath = path;
CFileFind fileFinder;
BOOL working = fileFinder.FindFile(path + "*.*");
while(working)
{
working = fileFinder.FindNextFile();
if (fileFinder.IsDots())
{
continue;
}
if (fileFinder.IsDirectory())
{
//subPath = subPath + fileFinder.GetFileName() + "/";
//findAllFile(subPath, fileNames, serverIP);
//cout<<"subPath:"<<subPath<<endl;
continue;
}
CString filename = fileFinder.GetFileName();
*fileNames = *fileNames + "<a href = HTTP://" + serverIP + "/" + filename + ">" + filename + "</a><br>";
}
}
/**************************
//在指定串中查找服务器IP
**************************/
void getIP(char* requstSrc)
{
char *IP = ::strstr(requstSrc, "Host:");
char host[10];
char sIP[30];
::sscanf(IP, "%s%s", host, sIP);
::memcpy(requstSrc, sIP, sizeof(sIP));
}
/*******************
//处理请求线程
*******************/
DWORD WINAPI AcceptProc(LPVOID lpParameter)
{
SOCKET* pSocket = (SOCKET*)lpParameter;
char buf[512];
memset(buf, 0, 512);
recv(*pSocket, buf, 512, 0); //接受请求内容
char commands[10];
char arguments[512];
char currentDirec[100];
memset(commands, 0 ,10);
memset(arguments, 0, 512);
memset(currentDirec, 0, 100);
::GetCurrentDirectory(100, currentDirec);
//访问服务器根目录
char rootDirec[512];
memcpy(rootDirec, currentDirec, sizeof(currentDirec));
memcpy(arguments, currentDirec, sizeof(currentDirec));
strcat(rootDirec, "/");
cout<<rootDirec<<endl;
sscanf(buf, "%s%s", commands, arguments + strlen(currentDirec));
cout<<arguments<<endl;
//判断请求方法
if (strcmp(commands, "GET") != 0)
{
cout<<"请求方法出错!"<<endl;
return -1;
}
if (strcmp(arguments, rootDirec) ==0)
{
//获取请求的服务器的IP及端口号
getIP(buf);
cout<<buf<<endl;
CString filenames;
findAllFile(arguments, &filenames, buf); //服务器根目录文件列表
cout<<filenames<<endl;
char content[1024];
memset(content, 0, 1024);
sprintf(content, "<head><title>index.html</title></head><body>%s</body>", filenames);
//发送目录给客户端
char head[2048];
memset(head, 0, 2048);
sprintf(head, "HTTP/1.1 200 OK/r/nContent-Type: text/html/r/nContent-Length: %d/r/n/r/n%s", sizeof(content), content);
send(*pSocket, head, strlen(head), 0);
closesocket(*pSocket);
}
else
{
//判断请求的文件是否存在
struct stat file_info;
int result = stat(arguments, &file_info);
if (result != 0)
{
cout<<"请求文件不存在"<<endl;
char content[512];
memset(content, 0 ,512);
sprintf(content, "<head><title>error.html</title></head><body>Not Found: %s</body>", arguments);
char response[1024];
memset(response, 0 ,1024);
sprintf(response, "HTTP/1.1 200 OK/r/nContent-Type: text/html/r/nContent-Length: %d/r/n/r/n%s", strlen(content), content);
send(*pSocket, response, sizeof(response), 0);
closesocket(*pSocket);
return -1;
}
//检查请求文件的类型
char *extension = ::strrchr(arguments, '.');
//cout<<extension+1<<endl;
char *Content_Type = "text/html";
if (strcmp(extension + 1, "html") == 0)
{
Content_Type = "text/html";
}
else if(strcmp(extension + 1, "jpg") == 0){
Content_Type = "image/jpeg";
}
//读取请求路径的文件
CFile readFrom(arguments, CFile::typeBinary); //以二进制格式传输
int fileLength = readFrom.GetLength();
char head[512];
memset(head, 0, 512);
sprintf(head, "HTTP/1.1 200 OK/r/nContent-Type: %s/r/nContent-Length: %d/r/n/r/n", Content_Type, fileLength);
int n = send(*pSocket, head, strlen(head), 0); //开始错误地用sizeof(head)
cout<<"n: "<<n<<endl;
memset(buf, 0, 512);
int left = 0;
int sended = 0;
int readNum = 0;
while(left < fileLength)
{
readNum = readFrom.Read(buf, 512);
sended = send(*pSocket, buf, readNum, 0);
left = left + sended;
}
}
closesocket(*pSocket);
return 0;
}
/*******************
//MIAN程序入口
*******************/
int main(int argc, char* argv[])
{
cout<<"********************************************"<<endl;
cout<<" WEB服务器启动..."<<endl;
cout<<"********************************************"<<endl;
SOCKET hSocket = createServerSocket();
while (true)
{
SOCKADDR_IN clientaddr;
int len = sizeof(SOCKADDR);
SOCKET newSocket = accept(hSocket, (SOCKADDR*)&clientaddr, &len);
//创建堆对象
SOCKET* pSocket = new SOCKET;
pSocket = &newSocket;
//创建线程处理客户端请求
HANDLE hThread = ::CreateThread(NULL, 0, AcceptProc, pSocket, 0, NULL);
::CloseHandle(hThread);
cout<<"创建客户端请求线程: "<<*pSocket<<endl;
}
::WSACleanup();
return 0;
}