简单http服务器代码
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
/*
基于流式套接字C/S结构的服务器端。
通信规程:
1、客户端连接到服务器以后,向服务器端发送命令
2、服务器解析命令的正确性,对于错误的命令,向客户端发送"Bad Command"的响应信息。
3、客户端主动断开连接,通过发送Quit命令实现。
4、服务器端在服务过程中,检测到错误后断开连接。
说明:
1、服务器工作在单线程select模型,所有处理都在main()中进行。
2、在该模式下,服务器并发为多个客户端提供服务
3、和基于非阻塞模式的单线程并发服务程序的区别是:
不要求套接字工作在非阻塞模式。
*/
//添加必要的头文件
//#define FD_SETSIZE 20
#include
#include
#define MAX_CLIENT_COUNT FD_SETSIZE-1
//用这种方式添加链接库信息
#pragma comment(lib,"ws2_32")
//服务器默认工作在7777端口,所有IP地址接收的连接请求都处理
#define DEFAULTPORT 7777
//接收、发送缓冲区大小
#define SIZE_INBUF 1024
#define SIZE_OUTBUF 1024
#define HTTP_SERVER_OUTPUT_HEAD "HTTP/1.1 200 OK\r\n" "Date: Wed,22nov 2000 02:44:34 GMT\r\n" "Server: Windows\r\n" "Last-Modified: Tue, 18 Apr 2000 13:24:10 GM T\r\n" "Accept-Ranges: bytes\r\n" "Content-Length: 121\r\n" "Connection: close\r\n" "Content-Type: text/html; charset=US-ASCII\r\n\r\n"
#define METHOD_NOT_IMPLEMENTED
"
Hello Word!
\r\n\r\n"int main(void)
{
//1 准备WinSock执行环境
WORD ver=MAKEWORD(2,2);
WSADATA wsdata;
intretCode;
retCode=WSAStartup(ver,&wsdata);
if(retCode)
{
printf("==========WinSock初始化失败!程序退出==========\n");
return -1;
}
printf("==========WinSock初始化成功!==========\n");
//2 创建套接字
SOCKET sockListen=INVALID_SOCKET;
sockListen=socket(AF_INET,SOCK_STREAM,0);
if(INVALID_SOCKET==sockListen)
{
printf("==========监听套接字创建失败!==========\n");
WSACleanup();
return -2;
}
printf("==========监听套接字[%d]创建成功!==========\n",sockListen);
//3 准备监听信息
sockaddr_inaddrServer;
//将地址信息结构体的所有字节均用0填充。填充时需要指定起始地址、填充内容和填充字节数
memset((void*)&addrServer,0,sizeof(sockaddr_in));
addrServer.sin_family=AF_INET;
addrServer.sin_port=htons(DEFAULTPORT);
addrServer.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
//4 将监听套接字绑定到特定地址(服务器端独有)
printf("监听套接字绑定到[%s:%d]......\n",inet_ntoa(addrServer.sin_addr),DEFAULTPORT);
retCode=bind(sockListen,(sockaddr*)&addrServer,sizeof(addrServer));
if(SOCKET_ERROR==retCode)
{
printf("绑定失败,错误代码:%d\n",WSAGetLastError());
closesocket(sockListen);
WSACleanup();
return -3;
}
printf("绑定成功\n");
boolkeepListening=true;
boolkeepWorking=true;
int i;
//定义保存套接字的数组
SOCKET Socks[MAX_CLIENT_COUNT];
for(i=0;i{
Socks[i]=INVALID_SOCKET;
}
//定义关注可读性网络事件的集合
fd_setfdread;
//5 进入监听状态
retCode=listen(sockListen,5);
if(SOCKET_ERROR==retCode)
{
printf("监听套接字不能正确进入监听状态,错误代码:%d\n",WSAGetLastError());
closesocket(sockListen);
WSACleanup();
return -4;
}
printf("成功进入监听状态......\n");
//7 应用层通信规程
//对于服务器端,一般是经常运行
SOCKET sockResponse=INVALID_SOCKET;
sockaddr_inaddrClient;
intaddrSize=sizeof(addrClient);
intrecvBytes=0;
charInBuf[SIZE_INBUF];
charOutBuf[SIZE_OUTBUF];
//保存客户端地址信息的字符数组,格式为IP地址:端口号
charClientInfo[20];
// char m_requestheader[1024];
//主循环
//超时间隔
timevaltv;
_sec=1;
_usec=0;
while(keepListening)
{
Hello Word!
\r\n\r\n"int main(void)
{
//1 准备WinSock执行环境
WORD ver=MAKEWORD(2,2);
WSADATA wsdata;
intretCode;
retCode=WSAStartup(ver,&wsdata);
if(retCode)
{
printf("==========WinSock初始化失败!程序退出==========\n");
return -1;
}
printf("==========WinSock初始化成功!==========\n");
//2 创建套接字
SOCKET sockListen=INVALID_SOCKET;
sockListen=socket(AF_INET,SOCK_STREAM,0);
if(INVALID_SOCKET==sockListen)
{
printf("==========监听套接字创建失败!==========\n");
WSACleanup();
return -2;
}
printf("==========监听套接字[%d]创建成功!==========\n",sockListen);
//3 准备监听信息
sockaddr_inaddrServer;
//将地址信息结构体的所有字节均用0填充。填充时需要指定起始地址、填充内容和填充字节数
memset((void*)&addrServer,0,sizeof(sockaddr_in));
addrServer.sin_family=AF_INET;
addrServer.sin_port=htons(DEFAULTPORT);
addrServer.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
//4 将监听套接字绑定到特定地址(服务器端独有)
printf("监听套接字绑定到[%s:%d]......\n",inet_ntoa(addrServer.sin_addr),DEFAULTPORT);
retCode=bind(sockListen,(sockaddr*)&addrServer,sizeof(addrServer));
if(SOCKET_ERROR==retCode)
{
printf("绑定失败,错误代码:%d\n",WSAGetLastError());
closesocket(sockListen);
WSACleanup();
return -3;
}
printf("绑定成功\n");
boolkeepListening=true;
boolkeepWorking=true;
int i;
//定义保存套接字的数组
SOCKET Socks[MAX_CLIENT_COUNT];
for(i=0;i { Socks[i]=INVALID_SOCKET; } //定义关注可读性网络事件的集合 fd_setfdread; //5 进入监听状态 retCode=listen(sockListen,5); if(SOCKET_ERROR==retCode) { printf("监听套接字不能正确进入监听状态,错误代码:%d\n",WSAGetLastError()); closesocket(sockListen); WSACleanup(); return -4; } printf("成功进入监听状态......\n"); //7 应用层通信规程 //对于服务器端,一般是经常运行 SOCKET sockResponse=INVALID_SOCKET; sockaddr_inaddrClient; intaddrSize=sizeof(addrClient); intrecvBytes=0; charInBuf[SIZE_INBUF]; charOutBuf[SIZE_OUTBUF]; //保存客户端地址信息的字符数组,格式为IP地址:端口号 charClientInfo[20]; // char m_requestheader[1024]; //主循环 //超时间隔 timevaltv; _sec=1; _usec=0; while(keepListening) {