一.浏览器与服务器的通信过程
浏览器与web服务器在应用层通信使用的是HTTP协议(超文本传输协议),是可靠的协议。而HTTP协议在传输层使用的是TCP协议,浏览器和web服务器三次握手建立连接后,才可以发送HTTP请求报文,服务器在收到请求报文后,向浏览器回复HTTP应答报文。
浏览器在向服务器发起连接前,需要得到服务器的IP和端口。用户在浏览器中只需要输入网址,浏览器会通过DNS服务查询获取到的服务器的IP地址,对于服务器来讲,使用HTTP协议的一般是80端口。
浏览器和服务器建立连接后,如果两次以上的请求重复使用一个TCP连接,我们称之为长连接。如果浏览器发送一次请求报文,服务器回复一次就断开连接,下次交互需要重新三次握手建立连接的,我们称之为短链接。
常见的web服务器有:
1.Apache:简单、速度快,性能稳定。可做代理服务器使用
2.IIS(Internet Information Server):安全性、强大、灵活
3.Nginx:小巧而高效,可以做高效的负载均衡反向代理
4.Tomcat:技术先进、性能稳定、免费
二.HTTP请求报头
1.HTTP请求报头结构
2.请求方法
3.应答报头结构

4.应答状态


三.代码
1.HTTP代码
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <fcntl.h>
#define PATH "/home/stu/桌面/c2305/day21"
int socket_init();
char* get_filename(char buff[])
{
char* ptr = NULL;//用来记录分隔到那里
char* s = strtok_r(buff," ",&ptr);//分隔字符串数组
if ( s == NULL )
{
return NULL;
}
printf("请求方法:%s\n",s);
s = strtok_r(NULL," ",&ptr);
return s;
}
void* thread_fun(void* arg)
{
int * p = (int*)arg;
int c = *p;
free(p);
while( 1 )
{
char buff[1024] = {0};
int n = recv(c,buff,1023,0);
if ( n <= 0 )
{
break;
}
printf("buff=\n%s\n",buff);
char* filename = get_filename(buff);
if ( filename == NULL )
{
break;
}
char path[256] = {PATH};// "/home/stu/桌面/c2305/day21"
if ( strcmp(filename,"/") == 0 )
{
filename = "/index.html";
}
strcat(path,filename);
printf("path:%s\n",path);
int fd = open(path,O_RDONLY);
if ( fd == -1 )
{
break;
}
int filesize = lseek(fd,0,SEEK_END);
lseek(fd,0,SEEK_SET);
char head[256] = {"HTTP/1.1 200 OK\r\n"};
strcat(head,"Server: myhttp\r\n");
sprintf(head+strlen(head),"Content-Length: %d\r\n",filesize);
strcat(head,"\r\n");
send(c,head,strlen(head),0);
char data[1024] = {0};
int num = 0;
while((num = read(fd,data,1024)) > 0 )
{
send(c,data,num,0);
}
close(fd);
//打开文件
//发送文件//报文头
}
close(c);
pthread_exit(NULL);
}
int main()
{
int sockfd = socket_init();
if ( sockfd == -1 )
{
exit(1);
}
while( 1 )
{
int c = accept(sockfd,NULL,NULL);
if ( c < 0 )
{
continue;
}
pthread_t id;
int *p = (int*)malloc(sizeof(int));
*p = c;
pthread_create(&id,NULL,thread_fun,(void*)p);
}
}
int socket_init()
{
int sockfd = socket(AF_INET,SOCK_STREAM,0);
if ( sockfd == -1)
{
return -1;
}
struct sockaddr_in saddr;
memset(&saddr,0,sizeof(saddr));
saddr.sin_family = AF_INET;
saddr.sin_port = htons(80);
saddr.sin_addr.s_addr = inet_addr("127.0.0.1");
int res = bind(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));
if ( res == -1 )
{
printf("bind err\n");
return -1;
}
if(listen(sockfd,5) == -1 )
{
return -1;
}
return sockfd;
}
2.html代码
<html>
<head>
<meta charset=utf8>
<title>主页</title>
</head>
<body background = "1.jpeg">
<center>
<h1>这是主页
</center>
</body>
</html>
~
~
~
~
~