关于http的理论知识可以点这里
http.c的代码展示:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define HOME_PATH "/home/su/2018/0403"//宏定义当前路径
int create_socket();
void* pthread_fun(void* c);
int main()
{
int sockfd = create_socket();
assert(sockfd != -1);
while(1)
{
struct sockaddr_in caddr;
int len = sizeof(caddr);
int c = accept(sockfd,(struct sockaddr*)&caddr,&len);
assert(c != 0);
printf("accept c = %d\n",c);
pthread_t id;
pthread_create(&id,NULL,pthread_fun,(void*)c);
}
}
void send_200ok(int c,int size)//组装http状态码200OK状态的应答报文头部字段
{
char http_head[512] = {"HTTP/1.1 200 OK\r\n"};
strcat(http_head,"Server: http\r\n");
sprintf(http_head+strlen(http_head),"Content-Length: %d\r\n",size);
strcat(http_head,"\r\n");//空行(http中用空行来分割,空行后面的是数据,前面的都是头部字段)
printf("\nsend:%s\n",http_head);
send(c,http_head,strlen(http_head),0);//发送应答报文
}
void send_404(int c)//组装http状态码404Not Found的应答报文头部字段
{
char http_head[512] = {"HTTP/1.1 404 Not Found\r\n"};
strcat(http_head,"Server: http\r\n");
strcat(http_head,"Content-Length: 10\r\n");
strcat(http_head,"\r\n");//空行
strcat(http_head,"Not Found!!!");
printf("\nsend:%s\n",http_head);
send(c,http_head,strlen(http_head),0);
}
void* pthread_fun(void* arg)
{
int c = (int)arg;
char buff[512] ={0};
int n = recv(c,buff,511,0);//接收http的请求报文
if(n <= 0 )
{
pthread_exit(NULL);//退出线程
}
printf("read:\n %s\n",buff);
// send(c,"hello",5,0);//发送http的应答报文
//组装报头
//send_200ok(c,5);
char * ptr = NULL;
char * s = strtok_r(buff," ",&ptr);
if(s == NULL)
{
close(c);
pthread_exit(NULL);
}
printf("Method:%s\n",s);
s = strtok_r(NULL," ",&ptr);
if(s == NULL)
{
close(c);
pthread_exit(NULL);
}
if(strcmp(s,"/") == 0)
{
s = "/index.html";
}
//send(c,"hello",5,0);
char path[256] = {HOME_PATH};
strcat(path,s);
printf("file path:%s\n",path);
int fd = open(path,O_RDONLY);//在本地以只读方式打开
if(fd == -1)
{
send_404(c);
close(c);
pthread_exit(NULL);
}
int size = lseek(fd,0,SEEK_END);//lseek函数是用来移动读写位置的,利用这个特性可以求文件大小
lseek(fd,0,SEEK_SET);//得出数据的大小
// sendfile(c,fd,NULL,size);
send_200ok(c,size);//发送文件内容
char readbuff[256] = {0};
int num = 0;
while((num = read(fd,readbuff,256))>0)
{
send(c,readbuff,num,0);
}
close(fd);
close(c);
}
int create_socket()//创建套接字
{
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 < 0)
{
return -1;
}
listen(sockfd,5);
return sockfd;
}
html文件内容展示:
1 <html>
2 <head>
3 <title>我的主页title>
4 head>
5
6 <body background = "zyx.jpg">
7 <center>
8 <h2>张艺兴是我男神!!!
9 <br>
10 center>
11 body>
12 html>
结果展示:
编译http文件注意两点:
1.必须是管理员权限。
2.在编译的时候要链接线程,在编译命令之后加上-pthread
这时在我们没有访问时处于阻塞状态。。。
访问linux中的火狐浏览器注意要打开网络连接哦!!!
如上图输入127.0.0.1/index.html
哈哈哈哈,张艺兴是我男神!!!(男神的图片必须最大)
好啦,那我们来看看刚刚阻塞的http.c文件执行后现在有什么信息?