Linux之访问internet上的web服务器(HTTP的应用)

关于http的理论知识可以点这里
http.c的代码展示:

#include<stdio.h>
#include<stdlib.h>
#include<fcntl.h>
#include<assert.h>
#include<unistd.h>
#include<string.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<pthread.h>

#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文件执行后现在有什么信息?
这里写图片描述

猜你喜欢

转载自blog.csdn.net/qq_39110766/article/details/79912437