#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <sys/socket.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#define MAX_READY_QUEUE 100
#define HTTP_PORT 80
#define BUFFER_SIZE 512
void *conn_thread(void *arg)
{
int sock_fd = (int)arg;
int read_len, file_size;
char buffer[BUFFER_SIZE];
char *str_ptr, *tmp_ptr, *ctype = "txt/html";
FILE *read_fp;
while (1) {
if ((read_len = read(sock_fd, buffer, BUFFER_SIZE - 1)) <= 0) {
printf("socket read error\n");
break;
}
buffer[read_len] = '\x00';
if ((str_ptr = strstr(buffer, "GET")) == NULL) {
continue;
}
strtok(str_ptr, " ?");
str_ptr = strtok(NULL, " ?") + 1;
printf("requested filename: %s\n", str_ptr);
if ((read_fp = fopen(str_ptr, "rb")) == NULL) {
printf("file not found\n");
sprintf(buffer, "HTTP/1.1 400 Bad Request\n"
"Content-length: 0\n\n");
write(sock_fd, buffer, BUFFER_SIZE);
break;
}
fseek(read_fp, 0, SEEK_END);
file_size = ftell(read_fp);
rewind(read_fp);
tmp_ptr = strtok(str_ptr, "./");
while (tmp_ptr) {
str_ptr = tmp_ptr;
tmp_ptr = strtok(NULL, "./");
}
printf("extension: %s\n", str_ptr);
if (str_ptr != NULL) {
if (strcasecmp(str_ptr, "gif") == 0) {
ctype = "image/gif";
} else if (strcasecmp(str_ptr, "jpg") == 0) {
ctype = "image/jpeg";
} else if (strcasecmp(str_ptr, "png") == 0) {
ctype = "image/png";
} else if (strcasecmp(str_ptr, "swf") == 0) {
ctype = "application/x-shockwave-flash";
}
}
sprintf(buffer, "HTTP/1.1 200 OK\n"
"Content-length: %d\n"
"Content-type: %s\n\n", file_size, ctype);
write(sock_fd, buffer, strlen(buffer));
while (!feof(read_fp)) {
read_len = fread(buffer, 1, BUFFER_SIZE - 1, read_fp);
if (read_len > 0) {
write(sock_fd, buffer, read_len);
}
}
fclose(read_fp);
}
close(sock_fd);
}
int main(void)
{
struct sockaddr_in address;
int sock, conn, i, curr;
size_t addrLength = sizeof(struct sockaddr_in);
char buff[512];
if ((sock = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
printf("socket creation error\n");
return -1;
}
memset(&address, 0, sizeof(address));
address.sin_family = AF_INET;
address.sin_port = htons(HTTP_PORT);
address.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(sock, (struct sockaddr *)&address, sizeof(address)) == -1) {
printf("bind address error\n");
return -1;
}
if (listen(sock, MAX_READY_QUEUE)) {
printf("listen error\n");
return -1;
}
while (1) {
pthread_t conn_tid;
conn = accept(sock, (struct sockaddr *)&address, &addrLength);
printf("new connection\n");
pthread_create(&conn_tid, NULL, conn_thread, (void*)conn);
}
}
'프로그래머의 길 > 리눅스' 카테고리의 다른 글
file server & client (0) | 2007.10.25 |
---|---|
[linux ver] echo server & client (0) | 2007.10.25 |
find 명령어 (0) | 2007.05.02 |
more / less / grep / egrep (0) | 2007.04.30 |
링크 (link) (0) | 2007.04.30 |