您的位置:首页 > 理论基础 > 计算机网络

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

2014-06-15 20:26 183 查看
一个简单的http服务器的实现
tkorays(tkorays@hotmail.com)
道理本身不重要,重要的是道理的实践。

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

简单实现

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

创建服务器端socket
创建服务器地址数据结构sockaddr_in
绑定端口,开始监听
循环,接收客户端的连接,从连接中获取客户端的socket以及地址sockaddr_in
接受数据,之后关闭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服务器,但是缺点也是不少的。

它没有解析请求,GET / 和GET /abc返回的都是一样的。
返回的东西已经写死,不能根据请求动态地返回,因此这里可以实现根据请求加载html文件。
响应头没有实现,对于浏览器的访问,服务器不是所有时候都是200 ok的。
每次连接后都会关闭客户端socket,完全可以保持连接状态,等待超时后再断开连接。
不支持并发,这里使用循环,如果同一时间还有其他的人访问服务器,那么他必须等待其他人访问完才行。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息