1.Web 服务器介绍
1.1web 服务器简介
Web 服务器又称 WWW 服务器、网站服务器等
特点
使用 HTTP 协议与客户机浏览器进行信息交流
不仅能存储信息,还能在用户通过 web 浏览器提供的信息的基础上运行脚本和程序
该服务器需可安装在 UNIX、Linux 或 Windows 等操作系统上
著名的服务器有 Apache、Tomcat、 IIS 等
1.2 HTTP 协议
Webserver—HTTP 协议
概念
一种详细规定了浏览器和万维网服务器之间互相通信的规则,通过因特网传送万维网文档的数据传送协议
特点
1、支持 C/S 架构
2、简单快速:客户向服务器请求服务时,只需传送请求方法和路径 ,常用方法:GET、POST
3、无连接:限制每次连接只处理一个请求且连接时间极短。
4、无状态:即如果后续处理需要前面的信息,它必须重传,这样可能导致每次连接传送的数据量会增大
1.3web服务器的通信过程
其实就是TCP协议的改良版,当传输时,严格按照上面的数据包格式进行数据的收发。
2.手把手写一个Web 编程的开发
Web服务器的开发
其实就是写一个tcp协议,不过我们要知道的是它的数据帧和要发送什么给网页
- 创建TCP套接字(socket)
- 绑定(bind)
- 监听(listen)
- 阻塞等待(accept)
- 创建多线程连接多个服务器
- 关闭套接字
#include <stdio.h>
#include <strings.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>
typedef struct {
int sockfd_new;
struct sockaddr_in cli_addr;
}My_args;
//访问资源失败头部
char err[]= "HTTP/1.1 404 Not Found\r\n" \
"Content-Type: text/html\r\n" \
"\r\n" \
"<HTML><BODY>File not found</BODY></HTML>";
//访问资源成功头部
char head[]="HTTP/1.1 200 OK\r\n" \
"Content-Type: text/html\r\n" \
"\r\n";
//处理客户端请求的线程函数
void * callback(void * arg){
My_args *p=( My_args* )arg;
char ip[16]="";
inet_ntop(AF_INET,&p->cli_addr.sin_addr.s_addr,ip,16);
printf("%s已连接服务器\n",ip);
char buf[1024]="";
char file[64]="";
int fd,len=0;
//接受消息
recv(p->sockfd_new,buf,sizeof(buf),0);
sscanf(buf,"GET /%s",file);//遇到空格也会停止
//打开文件
fd=open(file,O_RDWR);
//按照格式发送给浏览器
if(fd<0)
{
printf("文件不存在\n");
send(p->sockfd_new,err,strlen(err),0);
}
else
{
send(p->sockfd_new,head,strlen(head),0);
while(1)
{
memset(buf,0,sizeof(buf));
len=read(fd,buf,sizeof(buf));
send(p->sockfd_new,buf,len,0);
if(len<1024)
break;
}
}
printf("%s已断开服务器\n",ip);
close(p->sockfd_new);
if(p !=NULL){
free(p);
p=NULL;
}
return 0;
}
int main(int argc,char *argv[])
{
//创建套接字
int sockfd=socket(AF_INET,SOCK_STREAM,0);
if(sockfd<0)
{
printf("socket error\n");
return 0;
}
//设置端口复用
int yes=1;
setsockopt(sockfd, SOL_SOCKET,SO_REUSEADDR,&yes, sizeof(yes));
//服务器绑定
struct sockaddr_in my_addr;
bzero(&my_addr,sizeof(my_addr));
my_addr.sin_family=AF_INET;
my_addr.sin_port=htons(9000);
my_addr.sin_addr.s_addr=htonl(INADDR_ANY);
bind(sockfd,(struct sockaddr *)&my_addr,sizeof(my_addr));
//监听客户端
listen(sockfd,20);
struct sockaddr_in cli_addr;
socklen_t len=sizeof(cli_addr);
//用来跟客户端通信的套接字
int sockfd_new;
while(1){
bzero(&cli_addr,sizeof(cli_addr));
//提取客户端
sockfd_new=accept(sockfd,(struct sockaddr *)&cli_addr,&len);
My_args *p;
p=(My_args *)malloc(sizeof(My_args));
p->sockfd_new=sockfd_new;
p->cli_addr=cli_addr;
//创建线程
pthread_t pth;
pthread_create(&pth,NULL,callback,( void *)p);
pthread_detach(pth);
}
close(sockfd);
return 0;
}
编写好代码后在Linux下运行,这个时候可以认为web服务器是打开的,在浏览器上写输入网址我的是:http://10.36.145.33:9000/text.html
分别是你的服务器ip地址和端口号,后面跟着你要访问的html,如果有在你的目录下有text.html就会进行显示
否则就会提示错误