【HTTP】服务器代码<线程>

发布时间 2023-12-14 20:20:16作者: 素装写淡定
  1 #include <stdio.h>
  2 #include <pthread.h>
  3 #include <strings.h>
  4 #include <string.h>
  5 #include <unistd.h>
  6 #include <sys/socket.h>
  7 #include <netinet/in.h>
  8 #include <arpa/inet.h>
  9 #include <sys/types.h>
 10 #include <sys/stat.h>
 11 #include <fcntl.h>
 12 char err[] = "HTTP/1.1 404 Not Found\r\n"
 13              "Content-Type: text/html\r\n"
 14              "\r\n"
 15              "<HTML><BODY>File not found</BODY></HTML>";
 16 char head[] = "HTTP/1.1 200 OK\r\n"
 17               "Content-Type: text/html\r\n"
 18               "\r\n";
 19 // 线程
 20 void *recv_send_fun(void *arg)
 21 {
 22     int sockfd_new = *((int *)arg);
 23     char buf[1024] = "";
 24     char filebuf[1024] = "";
 25     char file[64] = "";
 26     int fd = 0;
 27     int len = 0;
 28     while (1)
 29     {
 30         bzero(buf, sizeof(buf));
 31         bzero(file, sizeof(file));
 32         // 接受浏览器发来的消息
 33         recv(sockfd_new, buf, sizeof(buf), 0);
 34         // 解析浏览器请求文件
 35         sscanf(buf, "GET /%s", file);
 36         fd = open(file, O_RDWR);
 37         if (fd > 0) // 判断文件是否存在
 38         {
 39             send(sockfd_new, head, strlen(head), 0);
 40             while (1)
 41             {
 42                 len = read(fd, filebuf, sizeof(filebuf));
 43                 send(sockfd_new, filebuf, len, 0);
 44                 if (len < 1024)
 45                     break;
 46             }
 47         }
 48         else
 49         {
 50             send(sockfd_new, err, strlen(err), 0);
 51         }
 52     }
 53     return NULL;
 54 }
 55 
 56 int main(int argc, char const *argv[])
 57 {
 58     // 1.创建套接字
 59     int sockfd = socket(AF_INET, SOCK_STREAM, 0);
 60     if (sockfd < 0)
 61     {
 62         perror("socket");
 63         return -1;
 64     }
 65     // 2.端口复用
 66     int yes = 1;
 67     setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (void *)&yes, sizeof(yes));
 68     // 3.绑定
 69     struct sockaddr_in my_addr;
 70     my_addr.sin_family = AF_INET;
 71     my_addr.sin_port = htons(8000);
 72     my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
 73     int ret = bind(sockfd, (struct sockaddr *)&my_addr, sizeof(my_addr));
 74     if (ret != 0)
 75     {
 76         perror("bind");
 77         return -1;
 78     }
 79     // 4.监听
 80     listen(sockfd, 10);
 81 
 82     struct sockaddr_in cli_addr;
 83     int len = sizeof(cli_addr);
 84     char ip[16] = "";
 85     unsigned short port = 0;
 86     int sockfd_new = 0;
 87     while (1)
 88     {
 89         // 5.保证提取到了正确的客户端
 90         sockfd_new = accept(sockfd, (struct sockaddr *)&cli_addr, &len);
 91         if (sockfd_new < 0)
 92             continue;
 93         // 6.创建线程
 94         pthread_t pth;
 95         pthread_create(&pth, NULL, recv_send_fun, (void *)&sockfd_new);
 96         pthread_detach(pth);
 97     }
 98     // 8.关闭套接字
 99     close(sockfd);
100     close(sockfd_new);
101     return 0;
102 }