簡單的使用linux下的select模型實現了一個HTTP的server

 

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <errno.h>
#include <netinet/in.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <stdlib.h>



#define LISTENQ 5
#define OPEN_MAX 1024
#define SERV_PORT 10088
#define MAX_LINE 1024
#define INFTIM -1



#define MAXEVENTS 1000





char szHtmlBuf[] = "HTTP/1.1 200 OK\r\n"
"Date: Sat, 05 Jan 2013 03:13:29 GMT\r\n"
"Vary: Accept-Encoding\r\n"
"Content-Type: text/html; charset=gb2312\r\n"
"Accept-Ranges: bytes\r\n"
"Content-Length: 57\r\n"
"\r\n"
"<html> <head>歡迎光臨</head> <body>屌絲逆襲季</body></html>";



fd_set fds;



void echo_srv(int clientFd)
{
處理使用者請求資料
char line[MAX_LINE];
printf( "開始讀取資料");
int n = read(clientFd, line, sizeof(line));
if(n < 0)
{
#define ECONNRESET 104 /* Connection reset by peer */
if(errno == ECONNRESET)
{
close(clientFd);
FD_CLR(clientFd, &fds);
printf("異常退出\n");
}
else
{
printf("網路異常");
exit(-1);
}
}
else if(n == 0)
{
close(clientFd);
FD_CLR(clientFd, &fds);
printf("正常退出\n");
}
else
{
line[n] = 0;
printf("接收到資料:%s\n", line);



write(clientFd, szHtmlBuf, sizeof(szHtmlBuf));
}
}



int main()
{
struct sockaddr_in cliaddr, servaddr;
int listenFd = socket(AF_INET, SOCK_STREAM, 0);
if( listenFd < 0)
{
printf("socket函數執行失敗");
return 1;
}

 

servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
inet_aton('10.132.10.64', &(servaddr.sin_addr));
servaddr.sin_addr.s_addr = inet_addr("10.132.10.64");
servaddr.sin_port = htons(SERV_PORT);
if(bind(listenFd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0)
{
printf("bind函數執行失敗");
return 1;
}

 

if(listen(listenFd, LISTENQ) < 0)
{
printf("listen函數執行失敗");
return 1;
}
printf("listen函數執行成功\n");

 

select 部分

 

int maxfd;
FD_ZERO(&fds);

 

do{
FD_SET(listenFd, &fds);
maxfd = listenFd + 1;
int nRead = 0;
if( (nRead = select(maxfd + 1, &fds, Null, Null, Null)) < 0)
{
printf("select 失敗\n");
exit(-1);
}
printf("select find data Change\n");
for(int i = 0; i <= maxfd && nRead > 0; i++)
{
if(!FD_ISSET(i, &fds))
{
continue;
}
--nRead;
if(i == listenFd)
{
socklen_t clilen = sizeof(cliaddr);
int connfd = accept(listenFd, (struct sockaddr*)&cliaddr, &clilen);
if(connfd < 0)
{
if ((errno != EAGAIN) && (errno != EWOULDBLOCK))
{
printf( "fail to accept new client \n");
continue;
}
}
printf("Ip: %s 到此一游\n", inet_ntoa(cliaddr.sin_addr));
FD_SET(connfd, &fds);
maxfd = (connfd > maxfd ? connfd : maxfd);
}
else
{
echo_srv(i);
}
}

 

}while(true);

 

return 0;
}

 

直接用瀏覽器進行測試即可:HTTP://伺服器Ip位址:10088
創作者介紹

資訊園

shadow 發表在 痞客邦 PIXNET 留言(0) 人氣()