一个简单的http服务器的实现

一个简单的http服务器的实现

tkorays(tkorays@hotmail.com)

道理本身不重要,重要的是道理的实践。


        想要写一个http服务器,其实也没有那么复杂?下面就来介绍一个简单的实现(windows平台),大致能够说明基本原理。


简单实现


        如果你写过tcp的应用的话,你会发现,其实它就是一个tcp服务器。因此我们完全可以把tcp的一些代码直接复制过来,下面的代码是一个简单的例子,大致步骤:

  1. 创建服务器端socket
  2. 创建服务器地址数据结构sockaddr_in
  3. 绑定端口,开始监听
  4. 循环,接收客户端的连接,从连接中获取客户端的socket以及地址sockaddr_in
  5. 接受数据,之后关闭socket等待下一次连接

        具体代码如下:

#include <WinSock2.h>
#include <stdio.h>
#pragma comment(lib,"ws2_32.lib")

int main(int argc, char** argv) {
	WSADATA wsadata;
	WSAStartup(MAKEWORD(2, 2), &wsadata);
	// 服务器的socket
	SOCKET server_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	sockaddr_in sv_sock_addr; // 服务器的地址
	sv_sock_addr.sin_family = AF_INET;
	sv_sock_addr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); // 服务器地址
	sv_sock_addr.sin_port = ntohs(8899); // 服务器的端口
	bind(server_sock, (sockaddr*)&sv_sock_addr, sizeof(sockaddr_in)); // 绑定
	listen(server_sock, 1); // 监听

	int addr_len = sizeof(sockaddr_in);
	sockaddr_in cl_sock_addr; // 客户端地址
	char buf[2048];
	while (true) {
		// 客户端的socket
		SOCKET client_sock = accept(server_sock, (sockaddr*)&cl_sock_addr, &addr_len);
		
		ZeroMemory(buf, 2048);
		recv(client_sock, buf, 2048, 0); // 接收数据
		printf("%s", buf);
		closesocket(client_sock);
	}
	closesocket(server_sock);
	WSACleanup();
	return 0;
}

        运行,打开浏览器,输入http://127.0.0.1:8899就可以看到控制台里面输出浏览器的请求:



        而浏览器里面却访问错误?



添加响应

        浏览器没有任何东西,这是因为,我们对于浏览器的请求并没有做出回应,因此,我们可以添加一些代码。

        在使用http协议时,注意下http响应的写法(可以参考http标准),下面的代码中简单地返回了带有响应头的字符串。这里没有解析接受的请求。

	int addr_len = sizeof(sockaddr_in);
	sockaddr_in cl_sock_addr; // 客户端地址
	char buf[2048];
	char retstr[] = "HTTP/1.1 200 OK\r\nServer:tkorays/0.0.1\r\nContent-Type: text/html\r\n\r\nhello world!";
	while (true) {
		// 客户端的socket
		SOCKET client_sock = accept(server_sock, (sockaddr*)&cl_sock_addr, &addr_len);
		
		ZeroMemory(buf, 2048);
		recv(client_sock, buf, 2048, 0); // 接收数据
		printf("%s", buf);
		send(client_sock, retstr, strlen(retstr), 0);
		closesocket(client_sock);
	}
	closesocket(server_sock);

        运行后再访问刚才的地址,发现浏览器里面出现了:



        如果是用火狐的开发者工具查看响应,你会看到下面的:


        就是我们刚才发送的响应头,响应的内容为“hello world!”


缺点&&下一步如何做?


        上面简单地实现了一个http服务器,但是缺点也是不少的。

  1. 它没有解析请求,GET / 和GET /abc返回的都是一样的。
  2. 返回的东西已经写死,不能根据请求动态地返回,因此这里可以实现根据请求加载html文件。
  3. 响应头没有实现,对于浏览器的访问,服务器不是所有时候都是200 ok的。
  4. 每次连接后都会关闭客户端socket,完全可以保持连接状态,等待超时后再断开连接。
  5. 不支持并发,这里使用循环,如果同一时间还有其他的人访问服务器,那么他必须等待其他人访问完才行。




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值