Server Develop (九) Simple Web Server
Simple Web Server
web服务器hello world!-----简单的socket通信实现。
HTTP
HTTP是Web浏览器与Web服务器之间通信的标准协议,HTTP指明了客户端如何与服务器建立连接,如果从服务器请求数据,服务器如何响应请求,关闭连接。HTTP是使用TCP/IP协议进行传输数据的,也就是传输层利用TCP进行连接,进行可靠连接的。
详情:点击
请求
一般格式,如:
GET /index.html HTTP/1.0
Accept:text/html,text/plain
User-Agent: Lyn
Host:www.server.com
我们主要需要的信息在第一行,共包括三个字段。
- 第一个字段(GET)为请求动作类型:
- GET代表请求的操作,表示要求服务器返回资源的表示;
- HEAD表示只需要文件的首部;
- PUT表示向服务器上传资源;
- POST主要是向服务器发送表单数据.
- 第二个字段(/index.html),标识服务器上所请求的资源的相对URL,必须要以"/"开头,Web浏览器在发送请求的时候会自动加上服务器的主机名。
- 第三个字段(HTTP/1.0),客户端理解的协议版本
注意:
每一个HTTP请求都要以两个回车换行结束(\r\n\r\n)
GET发送查询字符串主要直接将查询字符串附加到URL后面,如下表示:GET /index.html/user=XXX&Age HTTP/1.0
响应
一般格式,如
HTTP/1.1 200 OK
Date:Mon 15
Server:xxxxxx
Content-Type:text/html;
Content-length:xxx 代表文档的多少个字节,不包含首部字节数<html><head><title>Hello</title></head><body>Test</body></html>
我们需要大概构造这样的一个格式来回复浏览器。
所以,必须包含第一行的状态行、内容的格式、内容的长度和具体的内容。
实例
/* * A Simple Web Server */ #include <stdio.h> #include <string.h> #include <stdlib.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <error.h> #define PORT 9000 #define EOL "\r\n" #define EOL_SIZE 2 int recv_new(int fd, char *buffer); void send_new(int fd, char *msg); int main(int argc, char* argv[]) { int serv_fd; int client_fd; int ret; pid_t pid; struct sockaddr_in serv_addr; struct sockaddr_in client_addr; int len = sizeof(struct sockaddr_in); serv_fd = socket(AF_INET, SOCK_STREAM, 0); if(serv_fd < 0){ perror("create socket fail !\n"); exit(1); } bzero(&serv_addr, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = INADDR_ANY; serv_addr.sin_port = htons(PORT); int on = 1; ret = setsockopt(serv_fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(int)); if(ret < 0){ perror("setsockopt fail !\n"); exit(1); } ret = bind(serv_fd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)); if(ret < 0){ perror("bind fail !\n"); exit(1); } ret = listen(serv_fd, 5); if(ret < 0){ perror("listen fail !\n"); exit(1); } while(1){ client_fd = accept(serv_fd, (struct sockaddr*)&client_addr, &len); if(client_fd < 0){ perror("accept fail !\n"); continue; } char buffer[200]; recv_new(client_fd, buffer); printf("recv buffer: %s\n", buffer); char content[] = "<head><head><title>index.html</title></head><body>hello world!</body>"; char response[512]; sprintf(response, "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nContent-Length: %d\r\n\r\n%s", strlen(content), content); send(client_fd, response, sizeof(response), 0); close(client_fd); } return 0; } int recv_new(int fd, char *buffer) { char *p = buffer; // Use of a pointer to the buffer rather than dealing with the buffer directly int eol_matched = 0; // Use to check whether the recieved byte is matched with the buffer byte or not while (recv(fd, p, 1, 0) != 0) // Start receiving 1 byte at a time { if (*p == EOL[eol_matched]) // if the byte matches with the first eol byte that is '\r' { ++eol_matched; if (eol_matched == EOL_SIZE) // if both the bytes matches with the EOL { *(p + 1 - EOL_SIZE) = '\0'; // End the string return (strlen(buffer)); // Return the bytes recieved } } else { eol_matched = 0; } p++; // Increment the pointer to receive next byte } return (0); }
参考
http://computerdragon.blog.51cto.com/6235984/1191176
http://www.cnblogs.com/lynch_world/archive/2011/04/24/2026413.html
本文 由 cococo点点 创作,采用 知识共享 署名-非商业性使用-相同方式共享 3.0 中国大陆 许可协议进行许可。欢迎转载,请注明出处:
转载自:cococo点点 http://www.cnblogs.com/coder2012