c语言HTTP服务器,超级简易版。

算是对linux多线程的复习把,尝试这用socket写了一个简单的HTTP服务器,当访问它的时候它会给你发送一个HTML文件,这个HTML文件需要自己写。
代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <pthread.h>
#define BUF_SIZE 1024
#define SMALL_BUF 100
int flag = 0;
void* request_hander(void *arg);
void* content_type(char* file);
void send_error(FILE* fp);
void send_data(FILE* fp,char* ct, char* file_name);
void error_hander(char *message);
int main(int argc, char *argv[])
{
   int serv_sock,clnt_sock;
   struct sockaddr_in serv_addr,clnt_addr;
   socklen_t clt_sz = sizeof(clnt_addr);
   char buf[BUF_SIZE];
   pthread_t id_t;
   if(argc != 2)
   {
       printf("Usage : %s <port>\n",argv[0]); exit(1);
   }
   serv_sock = socket(PF_INET,SOCK_STREAM,0);
   memset(&serv_addr,0,sizeof(serv_addr));
   serv_addr.sin_family = AF_INET;
   serv_addr.sin_port = htons(atoi(argv[1]));
   serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
   if(bind(serv_sock,(struct sockaddr*)&serv_addr,sizeof(serv_addr)) == -1)
       error_hander("bind() error!");
   if(listen(serv_sock,20) == -1)
       error_hander("listen() error");
   while (1)
   {
       clnt_sock = accept(serv_sock,(struct sockaddr*)&clnt_addr,&clt_sz);
       printf("connection Request: %s:%d\n",inet_ntoa(clnt_addr.sin_addr),ntohs(clnt_addr.sin_port));
       pthread_create(&id_t,NULL,request_hander,&clnt_sock);
       pthread_detach(id_t);
   }
   close(serv_sock);
   return 0;
}
void* request_hander(void *arg)
{
    printf("进入 request_hander\n");
    int clnt_sock = *((int *)arg);
    char req_line[SMALL_BUF];
    FILE* clnt_read;
    FILE* clnt_write;

    char method[10];
    char ct[15];
    char file_name[30];

    clnt_read = fdopen(clnt_sock,"r");
    clnt_write = fdopen(dup(clnt_sock),"w");
    fgets(req_line,SMALL_BUF,clnt_read);
    printf("req_line= %s\n",req_line);
    if(strstr(req_line,"HTTP/") == NULL)
    {
        printf("mei you HTTP/\n");
        send_error(clnt_write);
        fclose(clnt_read);
        fclose(clnt_write);
        return ;
    }
    strcpy(method,strtok(req_line," /"));
    strcpy(file_name,strtok(NULL," /"));
    strcpy(ct,content_type(file_name));
    if(strcmp(method,"GET") != 0)
    {
        printf("mei you GET!\n");
        send_error(clnt_write);
        fclose(clnt_read);
        fclose(clnt_write);
        return ;
    }
    fclose(clnt_read);
    printf("filename= %s\n",file_name);
    send_data(clnt_write,ct,file_name);
}
void* content_type(char* file)
{
    char extension[SMALL_BUF];
    char file_name[SMALL_BUF];
    strcpy(file_name,file);
    strtok(file_name,".");
    strcpy(extension,strtok(NULL,"."));
    if( strcmp(extension,"html")==0 || strcmp(extension,"htm")==0 )
        return "text/html";
    return "text/plain";
}
void send_error(FILE* fp)
{
    printf("进入 send_error!\n");
    char protocol[] = "HTTP/1.0 400 Bad Request\r\n";
    char server[] = "Server: linux Web Server \r\n";
    char cnt_len[] = "Content-length:2048\r\n";
    char cnt_type[] = "content-type: text/html\r\n\r\n";
    char content[] = "<html> <head><title>NETWORK</title></head><body><font size=+5><br>error!!!</font></body></html>";
    fputs(protocol,fp);
    fputs(server,fp);
    fputs(cnt_type,fp);
    fputs(cnt_len,fp);
   fputs(content,fp);
    fflush(fp); // qing chu huan cun
}
void send_data(FILE* fp,char* ct, char* file_name)
{
    printf("进入send_data()\n");
    char protocol[] = "HTTP/1.0 200 OK\r\n";
    char server[] = "server: linux Web Server lian\r\n";
    char cnt_len[] = "Content-length: 2048\r\n";
    char cnt_type[SMALL_BUF];
    char buf[BUF_SIZE];
    FILE* send_file;
    sprintf(cnt_type,"Content-type:%s\r\n\r\n",ct);
    send_file = fopen(file_name,"r");
    if(send_file == NULL)
    {
        printf("wai cao\n");
        send_error(fp); return ;
    }
    fputs(protocol,fp);
    fputs(server,fp);
    fputs(cnt_len,fp);
    fputs(cnt_type,fp);
    while (fgets(buf,BUF_SIZE,send_file) != NULL)
    {
        printf("send_data wait()\n");
        fputs(buf,stdout);
        fputs(buf,fp);
        fflush(fp);
    }
    fflush(fp);
    fclose(fp);
}

void error_hander(char *message)
{
    fputs(message,stderr);
    fputc('\n',stderr);
    exit(1);
}

运行这个代码后,在浏览器中输入 http://127.0.0.1:xxxx/index.html。 xxxx是自己设的端口号。

  • 1
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值