Linux C语言实现的一个简单HTTP(包括客户端和服务器端以及HTTP用户验证)

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<netdb.h>
#include<signal.h>
#include<fcntl.h>

#define CONNMAX 1000
#define BYTES 1024

char *ROOT;
int listenfd,clients[CONNMAX];
void error(char *);
void startServer(char *);
void respond(int);
int main(int argc, char *argv[])
{
struct sockaddr_in clientaddr; //客户端地址变量
socklen_t addrlen;
char c;
char PORT[6]; //端口号
ROOT = getenv("PWD"); //当前目录
strcpy(PORT,"10000"); //端口设置为10000
int slot=0;
while((c=getopt(argc,argv,"p:r:"))!=-1)
{
switch(c)
{
case 'r':ROOT=malloc(strlen(optarg));
strcpy(PORT,optarg);break;
case 'p':
strcpy(PORT,optarg);break;
case '?':
fprintf(stderr,"Wrong arguments given!!\n");
exit(1);
default:
exit(1);
}
}
printf("Server started at port no,%s%s%s with root directory as %s%s %s\n","\033[92m",PORT,"\033[0m","\033[92m",ROOT,"\033[0m");
int i;
for(i=0;i<CONNMAX;i++)
{
clients[i]=-1;
}
startServer(PORT); //服务器开始工作
while(1)
{
addrlen = sizeof(clientaddr);
clients[slot] = accept(listenfd,(struct sockaddr *)
&clientaddr, &addrlen); //监听端口
if(clients[slot]<0)
{
error("accept() error"); //监听不到显示错误
}
else
{
if(fork() == 0)
{
respond(slot);
exit(0);
}
}
while(clients[slot]!=-1)
{
slot = (slot+1)%CONNMAX;
}
}
return 0;
}

void startServer(char *port)
{
struct addrinfo hints, *res, *p;
memset(&hints,0,sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;
if(getaddrinfo(NULL,port,&hints,&res)) //完成主机名到地址解析,非0失败
{
perror("getarrinfo() error");
exit(1);
}
for(p=res;p!=NULL;p=p->ai_next)
{
listenfd = socket(p->ai_family,p->ai_socktype,0);
if(listenfd == -1) continue;
if(bind(listenfd,p->ai_addr,p->ai_addrlen) == 0) break;//成功
}
if(p == NULL)
{
perror("sock() or bind()");
exit(1);
}
freeaddrinfo(res); //释放指针变量res
if(listen(listenfd,1000000)!=0)
{
perror("listen() error"); //监听失败
exit(1);
}
}

void respond(int n) //n为端口号
{
char mesg[99999], *reqline[3], data_to_send[BYTES],path[99999];
int rcvd,fd,bytes_read;
memset((void*)mesg,(int)'\0',99999);
rcvd=recv(clients[n],mesg,99999,0);
if(rcvd<0) //接受数据出错
{
fprintf(stderr,("recv() error\n"));
}
else if(rcvd == 0) //连接关闭
{
fprintf(stderr,"Client disconnected upexpectedly,\n");
}
else //接收到的数据大小
{
printf("We received the mesg is:%s",mesg);
if(strstr(mesg,"Authorization") == NULL)
{
write(clients[n],"HTTP/1.0 401 Unauthozied\r\nConnection:close\r\nContent-Type:text/html\r\nWWW-Authenticate:Basic realm='GM'\r\n\r\n",101);
printf("no Authorization header\n");
}
else
{
reqline[0] = strtok(mesg," ");
if(strncmp(reqline[0],"GET\0",4) == 0 )
{
reqline[1] = strtok(NULL," ");
reqline[2] = strtok(NULL,"\t\n");
printf("%s %s\n",reqline[1],reqline[2]);
if(strncmp(reqline[2],"HTTP/1.0",8)!=0 &&
strncmp(reqline[2],"HTTP/1.1",8)!=0)
{
write(clients[n],
"HTTP/1.0 400 Bad Request\n",25);
}
else
{
if( strncmp(reqline[1], "/", 2)==0)
{
reqline[1] = "/index.html";
}
strcpy(path,ROOT);
strcpy(&path[strlen(ROOT)],reqline[1]);
printf("file: %s\n",path);
if((fd=open(path,O_RDONLY))!=-1)
{
send(clients[n],
"HTTP/1.0 200 OK\n\n",17,0);
while((bytes_read=read(fd,
data_to_send,BYTES))>0) {
write(clients[n],
data_to_send,bytes_read);
}
} else {
write(clients[n],
"HTTP/1.0 404 Not Found\n",23);
}
}
}
}
}
shutdown(clients[n],2);
close(clients[n]);
clients[n]=-1;
}

 

转载于:https://www.cnblogs.com/Jackieg/p/5318689.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值