最简单的HTTP服务器实现,学习笔记
最近在学习HTTP服务器设计的相关知识,流连于网海之中,邂逅了Kevin Lynx老兄的博文《实现自己的HTTP Server》 链接如下:
http://www.cppblog.com/kevinlynx/archive/2008/07/30/57521.html
读了之后,觉得写得很好,原理和实现部分都阐述得浅显易懂。在看过文章后,又down了他写的代码下了看,今晚调试了一个最简单的HTTP Server的C实现的代码。对HTTP的原理总算有了些感性的认识,也才基本明白解析HTTP报文是怎么一回事,感觉无非就是解析一些字符串(现在学习的比较浅,莫嘲笑)。主要关键是了解HTTP报文的格式看代码就很清楚了。
代码还是得亲自去调试的,这和只是看一看还是有很大区别的!
在程序所在目录下建立一个最简单的HTML文件 index.html 。
内容为:
<head><head><title>index.html</title></head><body>index.html</body>
即可。
运行程序后,在你的浏览器中输入: http://localhost:8080/index.html 即可看到上面HTML文件的内容。这就完成了一个最基础的HTTP Server的功能了哦!同时,Kevin Lynx老兄还给出了一个完整的httpd library,正在学习了解中!非常感谢Kevin Lynx!
下面附上这个Server实现的代码:
/**
@file sample_httpd.c
@author Kevin Lynx
@brief sample httpd, just for testing purpose.
*/
#include <winsock2.h>
#include <stdio.h>
void http_response( SOCKET con, const char *request )
{
/* get the method */
char *token = strtok( request, " " );
char *uri = strtok( 0, " " );
//char *uri1 = strtok( 0, " " );
char file[64];
sprintf( file, ".%s", uri );
{
/* load the file content */
FILE *fp = fopen( file, "rb" );
if( fp == 0 )
{
/* response 404 status code */
char response[] = "HTTP/1.1 404 NOT FOUND\r\n\r\n";
send( con, response, strlen( response ), 0 );
}
else
{
/* response the resource */
/* first, load the file */
int file_size ;
char *content;
char response[1024];
fseek( fp, 0, SEEK_END );
file_size = ftell( fp );
fseek( fp, 0, SEEK_SET );
content = (char*)malloc( file_size + 1 );
fread( content, file_size, 1, fp );
content[file_size] = 0;
sprintf( response, "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nContent-Length: %d\r\n\r\n%s", file_size, content );
send( con, response, strlen( response ), 0 );
free( content );
}
}
}
int main()
{
WSADATA wd;
int ret;
SOCKET s;
ret = WSAStartup( MAKEWORD( 2, 0 ), &wd );
if( ret < 0 )
{
fprintf( stderr, "winsock startup failed\n" );
exit( -1 );
}
s = socket( AF_INET, SOCK_STREAM, 0 );
{
/* bind and listen */
struct sockaddr_in addr;
memset( &addr, 0, sizeof( addr ) );
addr.sin_family = AF_INET;
addr.sin_port = htons( 8080 );
addr.sin_addr.s_addr = inet_addr( "0.0.0.0" );
ret = bind( s, (struct sockaddr*)&addr, sizeof( addr ) );
if( ret < 0 )
{
fprintf( stderr, "bind failed\n" );
closesocket( s );
exit( -1 );
}
ret = listen( s, 1024 );
if( ret < 0 )
{
fprintf( stderr, "listen failed\n" );
closesocket( s );
exit( -1 );
}
}
{
SOCKET con = accept( s, 0, 0 );
/* recv request */
char request[1024] = { 0 };
ret = recv( con, request, sizeof( request ), 0 );
printf( request );
http_response( con, request );
closesocket( con );
}
closesocket( s );
WSACleanup();
return 0;
}
多思考,多总结,快乐成长!

浙公网安备 33010602011771号