红联Linux门户
Linux帮助

自己结合例子改的一个HTTP服务器

发布时间:2010-05-08 14:52:38来源:红联作者:静静飞舞
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

#define SERVER_IP "127.0.0.1"
#define NOFILE 256
#define MAXBUF 1024
#define MAXPATH 150

char ip[128];
char port[128];
char back[128];
char home_dir[128];
char buffer[MAXBUF + 1];

void init_deamon(const char *pname, int facility) { //set the process to wait-process
int pid;
int i;
signal(SIGTTOU, SIG_IGN);
signal(SIGTTIN, SIG_IGN);
signal(SIGTSTP, SIG_IGN);
signal(SIGHUP, SIG_IGN);
if (pid = fork())
exit(EXIT_SUCCESS);
else if (pid < 0) {
perror("socket!");
exit(EXIT_FAILURE);
}
setsid();
if (pid = fork())
exit(EXIT_SUCCESS);
else if (pid < 0) {
perror("socket!");
exit(EXIT_FAILURE);
}
for (i = 0; i < NOFILE; i++)
close(i);
open("/dev/null", O_RDONLY);
open("/dev/null", O_RDWR);
open("/dev/null", O_RDWR);
chdir("/tmp");
umask(0);
signal(SIGCHLD, SIG_IGN);
openlog(pname, LOG_PID, facility);
return;
}
void write_log(char *msg){
syslog(LOG_INFO, "%s", msg);
}
int get_arg(char *cmd) { //read the configure file
FILE *fp;
char buffer[1024];
size_t bytes_read;
char* match;
fp = fopen("/root/NetBeansProjects/LINUX-Design/test_httpd.conf", "r");
bytes_read = fread(buffer, 1, sizeof (buffer), fp);
fclose(fp);
if (bytes_read == 0 || bytes_read == sizeof (buffer))
return 0;
buffer[bytes_read] = '\0';
if (!strncmp(cmd, "home_dir", 8)) {
match = strstr(buffer, "home_dir=");
if (match == NULL)
return 0;
bytes_read = sscanf(match, "home_dir=%s", home_dir);
return bytes_read;
} else if (!strncmp(cmd, "port", 4)) {
match = strstr(buffer, "port=");
if (match == NULL)
return 0;
bytes_read = sscanf(match, "port=%s", port);
return bytes_read;
} else if (!strncmp(cmd, "ip", 2)) {
match = strstr(buffer, "ip=");
if (match == NULL)
return 0;
bytes_read = sscanf(match, "ip=%s", ip);
return bytes_read;
} else if (!strncmp(cmd, "back", 4)) {
match = strstr(buffer, "back=");
if (match == NULL)
return 0;
bytes_read = sscanf(match, "back=%s", back);
return bytes_read;
} else
return;
}
int make_server_socket() {
struct sockaddr_in addr;
int sock_fd, addrlen;

if (get_arg("home_dir") == 0) {
sprintf(home_dir, "%s", "/tmp");
}
if (get_arg("ip") == 0) {
get_addr("eth0");
}
if (get_arg("port") == 0) {
sprintf(port, "%s", "80");
}
if (get_arg("port") == 0) {
sprintf(back, "%s", "5");
}
if ((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
write_log("socket!");
exit(EXIT_FAILURE);
}
addrlen = 1;
setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, &addrlen, sizeof (addrlen));

addr.sin_family = AF_INET;
addr.sin_port = htons(atoi(port));
addr.sin_addr.s_addr = inet_addr(ip);
addrlen = sizeof (struct sockaddr_in);
if (bind(sock_fd, &addr, sizeof (addr)) < 0) {
write_log("bind!");
exit(EXIT_FAILURE);
}
if (listen(sock_fd, 5) < 0) {
write_log("listen!");
exit(EXIT_FAILURE);
}
return sock_fd;
}
char *dir_up(char *dirpath){
static char Path[MAXPATH];
int len;
strcpy(Path, dirpath);
len = strlen(Path);
if (len > 1 && Path[len - 1] == '/')
len--;
while (Path[len - 1] != '/' && len > 1)
len--;
Path[len] = 0;
return Path;
}
void response(FILE *client_sock, char *Path) {
struct dirent *dirent;
struct stat info;
char Filename[MAXPATH];
DIR *dir;
int fd, len, ret;
char *p, *realPath, *realFilename, *nport;
/* 获得实际工作目录或文件 */
len = strlen(home_dir) + strlen(Path) + 1;
realPath = malloc(len + 1);
bzero(realPath, len + 1);
sprintf(realPath, "%s/%s", home_dir, Path);
/* 获得实际工作端口 */
len = strlen(port) + 1;
nport = malloc(len + 1);
bzero(nport, len + 1);
sprintf(nport, ":%s", port);
/* 获得实际工作目录或文件的信息以判断是文件还是目录 */
if (stat(realPath, &info)) {

fprintf(client_sock,

"HTTP/1.1 200 OK\r\nServer: DAS by ZhouLifa\r\nConnection: close\r\n\r\n%d - %s"

"Linux HTTP SERVER


"

"", errno,

strerror(errno));

fprintf(client_sock,

"
connect to administrator,error code is:\n%s %s",

Path, strerror(errno));

goto out;

}

/* 处理浏览文件请求,即下载文件 */
if (S_ISREG(info.st_mode)) {
fd = open(realPath, O_RDONLY);
len = lseek(fd, 0, SEEK_END);
p = (char *) malloc(len + 1);
bzero(p, len + 1);
lseek(fd, 0, SEEK_SET);
ret = read(fd, p, len);
close(fd);
fprintf(client_sock,
"HTTP/1.1 200 OK\r\nServer: linux HTTP SERVER\r\nConnection: keep-alive\r\nContent-type: application/*\r\nContent-Length:%d\r\n\r\n",

len);
fwrite(p, len, 1, client_sock);
free(p);
} else if (S_ISDIR(info.st_mode)) {
/* 处理浏览目录请求 */
dir = opendir(realPath);
fprintf(client_sock,

"HTTP/1.1 200 OK\r\nServer: linux HTTP SERVER\r\nConnection: close\r\n\r\n%s"

"Linux Http Server File


"

"", Path);

fprintf(client_sock,
"\n",
Path);
fprintf(client_sock,
"\n");
if (dir == 0) {
fprintf(client_sock,
"
name %s
namesizemodify time
%s",
strerror(errno));
return;
}
/* 读取目录里的所有内容 */
while ((dirent = readdir(dir)) != 0) {
if (strcmp(Path, "/") == 0)
sprintf(Filename, "/%s", dirent->d_name);
else
sprintf(Filename, "%s/%s", Path, dirent->d_name);
fprintf(client_sock, "");
len = strlen(home_dir) + strlen(Filename) + 1;
realFilename = malloc(len + 1);
bzero(realFilename, len + 1);
sprintf(realFilename, "%s/%s", home_dir, Filename);
if (stat(realFilename, &info) == 0) {
if (strcmp(dirent->d_name, "..") == 0)
fprintf(client_sock,
"(parent)",
ip, atoi(port) == 80 ? "" : nport,
dir_up(Path));
else
fprintf(client_sock,
"%s",
ip, atoi(port) == 80 ? "" : nport, Filename,
dirent->d_name);
if (S_ISDIR(info.st_mode))
fprintf(client_sock, "d");
else if (S_ISREG(info.st_mode))
fprintf(client_sock, "%d", info.st_size);
else if (S_ISLNK(info.st_mode))
fprintf(client_sock, "l");
else if (S_ISCHR(info.st_mode))
fprintf(client_sock, "c");
else if (S_ISBLK(info.st_mode))
fprintf(client_sock, "b");
else if (S_ISFIFO(info.st_mode))
fprintf(client_sock, "FIFO");
else if (S_ISSOCK(info.st_mode))
fprintf(client_sock, "Socket");
else
fprintf(client_sock, "Don`t know");
fprintf(client_sock, "%s", ctime(&info.st_ctime));
}
fprintf(client_sock, "\n");
free(realFilename);
}
fprintf(client_sock, "
");
} else {
/* 既非常规文件又非目录,禁止访问 */
fprintf(client_sock,
"HTTP/1.1 200 OK\r\nServer: DAS by ZhouLifa\r\nConnection: close\r\n\r\npermission denied"
"Linux Http Server File


"
"");
fprintf(client_sock,
"
you access resourse'%s'forbid to access,communicate with the administrator",
Path);
}
out:
free(realPath);
free(nport);
}
int get_addr(char *str) {
int inet_sock;
struct ifreq ifr;
inet_sock = socket(AF_INET, SOCK_STREAM, 0);
strcpy(ifr.ifr_name, "eth0");
if (ioctl(inet_sock, SIOCGIFADDR, &ifr) < 0) {
write_log("bind");
exit(EXIT_FAILURE);
}
sprintf(ip, "%s", inet_ntoa(((struct sockaddr_in *) &(ifr.ifr_addr))->sin_addr));
}
int main(int argc, char** argv) {
int sock_fd, new_fd, len, addrlen;
struct sockaddr_in addr,c_addr;
pid_t pid;

init_deamon(argv[0], LOG_INFO);
if (get_arg("home_dir") == 0) {
sprintf(home_dir, "%s", "/tmp");
}
if (get_arg("ip") == 0) {
get_addr("eth0");
}
if (get_arg("port") == 0) {
sprintf(port, "%s", "80");
}
if (get_arg("port") == 0) {
sprintf(back, "%s", "5");
}
if ((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
write_log("socket!");
exit(EXIT_FAILURE);
}
addrlen = 1;
setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, &addrlen, sizeof (addrlen));

addr.sin_family = AF_INET;
addr.sin_port = htons(atoi(port));
addr.sin_addr.s_addr = inet_addr(ip);
addrlen = sizeof (struct sockaddr_in);
if (bind(sock_fd, &addr, sizeof (addr)) < 0) {
write_log("bind!");
exit(EXIT_FAILURE);
}
if (listen(sock_fd, 5) < 0) {
write_log("listen!");
exit(EXIT_FAILURE);
}

while (1) {
addrlen = sizeof (struct sockaddr_in);
len = sizeof (struct sockaddr);
printf("Waiting for a new connect........\n");
if (new_fd = accept(sock_fd, &c_addr, &len) < 0) {
write_log("accept!");
exit(EXIT_FAILURE);
}
bzero(buffer, MAXBUF + 1);
sprintf(buffer, "Server got connection from %s, port: %d\n", inet_ntoa(c_addr.sin_addr), ntohs(c_addr.sin_port));
write_log(buffer);
if ((pid = fork()) == -1) {
write_log("accept!");
exit(EXIT_FAILURE);
}
if (pid == 0) {
close(sock_fd);
bzero(buffer, MAXBUF + 1);
if ((len = recv(new_fd, buffer, MAXBUF, 0)) > 0) {
FILE *ClientFP = fdopen(new_fd, "w");
if (ClientFP == NULL) {
write_log("fdopen");
exit(EXIT_FAILURE);
} else {
char Req[MAXBUF + 1] = "";
sscanf(buffer, "GET %s HTTP", Req);
bzero(buffer, MAXBUF + 1);
sprintf(buffer, "Request get the file: \"%s\"\n", Req);
write_log(buffer);
response(ClientFP, Req);
fclose(ClientFP);
}
}
exit(EXIT_SUCCESS);
} else {
close(new_fd);
continue;
}
}
close(sock_fd);
return 0;
}
文章评论

共有 2 条评论

  1. xx009 于 2010-06-18 11:11:41发表:

    进来看看

  2. 不吐不快行不 于 2010-05-12 19:55:33发表:

    关注 关注......谢谢!!!