最简单的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;
}
posted @ 2010-03-27 21:27  酷酷的小鱼儿  阅读(5408)  评论(4编辑  收藏  举报