Simple Web Server
web服務(wù)器hello world!-----簡(jiǎn)單的socket通信實(shí)現(xiàn)。
HTTP
HTTP是Web瀏覽器與Web服務(wù)器之間通信的標(biāo)準(zhǔn)協(xié)議,HTTP指明了客戶端如何與服務(wù)器建立連接,如果從服務(wù)器請(qǐng)求數(shù)據(jù),服務(wù)器如何響應(yīng)請(qǐng)求,關(guān)閉連接。HTTP是使用TCP/IP協(xié)議進(jìn)行傳輸數(shù)據(jù)的,也就是傳輸層利用TCP進(jìn)行連接,進(jìn)行可靠連接的。
詳情:點(diǎn)擊
請(qǐng)求
一般格式,如:
GET /index.html HTTP/1.0
Accept:text/html,text/plain
User-Agent: Lyn
Host:www.server.com
我們主要需要的信息在第一行,共包括三個(gè)字段。
- 第一個(gè)字段(GET)為請(qǐng)求動(dòng)作類型:
- GET代表請(qǐng)求的操作,表示要求服務(wù)器返回資源的表示;
- HEAD表示只需要文件的首部;
- PUT表示向服務(wù)器上傳資源;
- POST主要是向服務(wù)器發(fā)送表單數(shù)據(jù).
- 第二個(gè)字段(/index.html),標(biāo)識(shí)服務(wù)器上所請(qǐng)求的資源的相對(duì)URL,必須要以"/"開頭,Web瀏覽器在發(fā)送請(qǐng)求的時(shí)候會(huì)自動(dòng)加上服務(wù)器的主機(jī)名。
- 第三個(gè)字段(HTTP/1.0),客戶端理解的協(xié)議版本
注意:
每一個(gè)HTTP請(qǐng)求都要以兩個(gè)回車換行結(jié)束(\r\n\r\n)
GET發(fā)送查詢字符串主要直接將查詢字符串附加到URL后面,如下表示:GET /index.html/user=XXX&Age HTTP/1.0
響應(yīng)
?一般格式,如
HTTP/1.1 200 OK
Date:Mon 15
Server:xxxxxx
Content-Type:text/html;
Content-length:xxx 代表文檔的多少個(gè)字節(jié),不包含首部字節(jié)數(shù)
<html><head><title>Hello</title></head><body>Test</body></html>
我們需要大概構(gòu)造這樣的一個(gè)格式來(lái)回復(fù)瀏覽器。
所以,必須包含第一行的狀態(tài)行、內(nèi)容的格式、內(nèi)容的長(zhǎng)度和具體的內(nèi)容。
實(shí)例
/** 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 2int 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 directlyint eol_matched = 0; // Use to check whether the recieved byte is matched with the buffer byte or notwhile (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 stringreturn (strlen(buffer)); // Return the bytes recieved }} else {eol_matched = 0;}p++; // Increment the pointer to receive next byte }return (0); }本文轉(zhuǎn)自cococo點(diǎn)點(diǎn)博客園博客,原文鏈接:http://www.cnblogs.com/coder2012/p/3402221.html,如需轉(zhuǎn)載請(qǐng)自行聯(lián)系原作者
總結(jié)
以上是生活随笔為你收集整理的Simple Web Server的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: curl 伪装来路(referer)
- 下一篇: asp教程七:包含文件