首先分析http协议的报头数据
1: GET /index.html HTTP/1.1
2: Host: localhost:8000
3: User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:10.0.1) Gecko/20100101 Firefox/10.0.1
4: Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
5: Accept-Language: en-us,en;q=0.5
6: Accept-Encoding: gzip, deflate
7: Connection: keep-alive
得到第一行数据GET /index.html /HTTP/1.1
建立一个简单的web程序,大致流程与笔记一种类型
直接贴代码了
服务端代码:
1: /**
2: ** web_server.c
3: ** copyright Xu Dongdong 2013.5.9 Open Source Software License.
4: */
5:
6: #include <stdio.h>
7: #include <stdlib.h> /*exit */
8: #include <string.h> /*memset*/
9: #include <sys/socket.h>
10: #include <netinet/in.h>
11: #include <arpa/inet.h>
12: #include <netdb.h>
13: #include <errno.h>
14:
15: unsigned short int port = 8000;
16:
17: char *error_return = "<html> \n <body> File bnot found </body> </html>" ;
18: char ret_buf[32768];
19: char *read_file(char * buf ,int num_buf);
20:
21: int main (int argc ,char*argv[])
22: {
23:
24: char * recvBuffer = (char * )malloc(4001);
25:
26: int rc;
27:
28: struct sockaddr_in serv_addr;
29: struct sockaddr_in cli_addr;
30:
31: int sockfd;
32: struct hostent* entity;
33: int total_recv, total_sent,bytes_sent,total_size,size;
34: int sockfd_tmp;
35: int addr_size;
36:
37: char *buf;
38: int i,len;
39:
40: sockfd = socket(AF_INET, SOCK_STREAM,0);
41: if(sockfd == -1)
42: {
43: perror("call to socket error");
44: exit(1);
45: }
46: memset(&serv_addr,'\0',sizeof(serv_addr));
47: serv_addr.sin_family = AF_INET;
48: serv_addr.sin_addr.s_addr= htonl(INADDR_ANY);
49: serv_addr.sin_port = htons(port);
50:
51:
52: if(bind(sockfd,(struct sockaddr *)&serv_addr ,sizeof(serv_addr)) == -1)
53: {
54: perror("call to bind error");
55: exit(1);
56: }
57:
58: if(listen(sockfd,20) == -1)
59: {
60: perror("call to listen error");
61: exit(1);
62: }
63:
64: printf("Accepting connections ......\n");
65:
66: while(1)
67: {
68: rc = sizeof(struct sockaddr_in);
69: do{
70: sockfd_tmp = accept(sockfd,(struct sockaddr*)&cli_addr,&rc);
71: }while( sockfd_tmp == -1 && errno == EINTR);
72: if(sockfd_tmp == -1)
73: {
74: perror("call to accept error");
75: exit(1);
76: }
77:
78: entity = gethostbyaddr((char*)&cli_addr.sin_addr ,sizeof (struct in_addr),AF_INET);
79: i = recv(sockfd_tmp,recvBuffer,4000,0) ;
80: if(i == -1)
81: {
82: perror("call to recv error");
83: break;
84: }
85: if(recvBuffer[i-1] != '\n') break;
86: recvBuffer[i] = '\0' ;
87:
88: printf("receive from client:%s\n",recvBuffer);
89:
90: buf = read_file(recvBuffer, total_recv);
91: size = strlen(buf);
92: total_sent = 0;
93:
94: do{
95: bytes_sent = send(sockfd_tmp ,buf+total_sent, strlen(buf + total_sent) ,0);
96: if(bytes_sent == -1)
97: {
98: break;
99: }
100: total_sent += bytes_sent;
101: }while(total_size < size) ;
102:
103: close(sockfd_tmp);
104: }
105:
106: return EXIT_SUCCESS;
107: }
108:
109: char* read_file(char * buf ,int num_buf)
110: {
111: int i ;
112: char * cp, *cp2 ;
113: FILE * file;
114: cp =buf +5 ;
115: cp2 = strstr(cp ," HTTP");
116: if(cp2 != NULL )
117: {
118: *cp2 = '\0' ;
119: }
120:
121: file = fopen(cp ,"r");
122: if(file == NULL )
123: {
124: return error_return;
125: }
126: i= fread(ret_buf ,1 ,32768 ,file);
127:
128: if(i==0)
129: {
130: fclose(file);
131: return error_return;
132: }
133:
134: ret_buf[i] = '\0';
135: fclose(file);
136: return ret_buf;
137: }
客户端代码:
1: /**
2: ** client.c
3: ** copyright Xu Dongdong 2013.5.9 Open Source Software License.
4: */
5:
6: #include <stdio.h>
7: #include <stdlib.h>
8: #include <string.h>
9:
10: #include <sys/socket.h>
11: #include <netinet/in.h>
12: #include <arpa/inet.h>
13: #include <netdb.h>
14:
15: char * host_name = "127.0.0.1"; //local host
16: unsigned int port = 8000 ;
17:
18: int main (int argc ,char*argv[])
19: {
20: char buf[8192];
21: char message[256];
22:
23: struct sockaddr_in cli_addr;
24:
25: int sockfd;
26: struct hostent *serv_host_name;
27:
28:
29: if((serv_host_name = gethostbyname(host_name)) ==0)
30: {
31: perror("Error resolving local host \n");
32: exit(1);
33: }
34:
35:
36: sockfd = socket(AF_INET, SOCK_STREAM,0);
37: if(sockfd == -1)
38: {
39: perror("call to socket error");
40: exit(1);
41: }
42:
43: memset(&cli_addr,'\0',sizeof(cli_addr));
44: cli_addr.sin_family = AF_INET;
45: cli_addr.sin_addr.s_addr= htonl(INADDR_ANY);
46: cli_addr.sin_addr.s_addr = (( ( struct in_addr *)(serv_host_name -> h_addr) )-> s_addr);
47: cli_addr.sin_port = htons(port);;
48:
49: if(connect(sockfd,(void *)&cli_addr ,sizeof(cli_addr)) == -1)
50: {
51: perror("call to connet to socket ");
52: exit(1);
53: }
54:
55: sprintf(message,"GET /index.html HTTP/1.1 \n");
56: printf("Sending message %s to web_server ... \n", message);
57:
58: if(send(sockfd,message,strlen(message), 0) == -1)
59: {
60: printf("call to send error");
61: exit(1);
62: }
63:
64: printf("...sent message...wait for response \n");
65:
66: if(recv(sockfd,buf,8192,0) == -1)
67: {
68: perror("error in receiving response from server ");
69: exit(1);
70: }
71: printf("Respnse from server:%s\n",buf);
72:
73: close(sockfd);
74: }
75:
直接使用gcc编译运行即可
可以使用浏览器作为客户端进行访问,具体的url为: http://localhost:8000/index.html
作为实例我们给出最简单你的html代码 index.html
1: <html>
2: <head>
3: </head>
4: <body>
5: index.html
6: </body>
7: </html>