makefile
CC = gcc
CFLAGS = -Wall
LDFLAGS =
List of source files
SRCS = server_mutil_proc.c server_mutil_thread.c server_IO.c
Generate names for object files
OBJS = $(SRCS:.c=.o)
Targets
all: server_mutil_proc server_mutil_thread server_IO
server_mutil_proc: server_mutil_proc.o
$(CC) $(CFLAGS) $(LDFLAGS) server_mutil_proc.o -o server_mutil_proc
server_mutil_thread: server_mutil_thread.o
$(CC) $(CFLAGS) $(LDFLAGS) server_mutil_thread.o -o server_mutil_thread -pthread
server_IO: server_IO.o
$(CC) $(CFLAGS) $(LDFLAGS) server_IO.o -o server_IO
Generic rule for compiling .c files to .o files
%.o: %.c
$(CC) $(CFLAGS) -c $<
clean:
rm -f *.o server_mutil_proc server_mutil_thread server_IO
添加日志输出的server代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#define PORT 8080
#define MAXLINE 1024
FILE *log_file; // Global variable for log file pointer
void init_log(const char *log_filename) {
log_file = fopen(log_filename, “a”); // Open log file in append mode
if (log_file == NULL) {
perror(“Error opening log file”);
exit(EXIT_FAILURE);
}
fprintf(log_file, “=== Server started ===\n”);
}
void close_log() {
fprintf(log_file, “=== Server closed ===\n”);
fclose(log_file);
}
void send_response(int client_fd, const char *response) {
send(client_fd, response, strlen(response), 0);
}
void serve_file(int client_fd, const char *filename) {
FILE *file = fopen(filename, “r”);
if (file == NULL) {
fprintf(log_file, “Error opening file: %s\n”, filename);
char response[MAXLINE];
sprintf(response, “HTTP/1.1 404 Not Found\r\n”
“Content-Type: text/plain\r\n”
“\r\n”
“404 Not Found: File not found”);
send_response(client_fd, response);
return;
}
char file_contents[MAXLINE];
fread(file_contents, sizeof(char), MAXLINE, file);
fclose(file);
char response[MAXLINE];
sprintf(response, "HTTP/1.1 200 OK\r\n"
"Content-Type: text/html\r\n"
"\r\n"
"%s", file_contents);
send_response(client_fd, response);
fprintf(log_file, "Served file: %s\n", filename);
}
void handle_request(int client_fd) {
char buffer[MAXLINE];
int bytes_read = read(client_fd, buffer, sizeof(buffer) - 1);
if (bytes_read < 0) {
perror(“Error reading from socket”);
return;
}
buffer[bytes_read] = ‘\0’;
// Log the request
fprintf(log_file, "Request received:\n%s\n", buffer);
char method[MAXLINE], path[MAXLINE];
sscanf(buffer, "%s %s", method, path);
if (strcasecmp(method, "GET") == 0) {
if (strcmp(path, "/") == 0) {
// Serve index.html if available
if (access("index.html", F_OK) != -1) {
serve_file(client_fd, "index.html");
} else if (access("Index.html", F_OK) != -1) {
serve_file(client_fd, "Index.html");
} else {
fprintf(log_file, "404: Neither index.html nor Index.html found\n");
char response[MAXLINE];
sprintf(response, "HTTP/1.1 404 Not Found\r\n"
"Content-Type: text/plain\r\n"
"\r\n"
"404 Not Found: File not found");
send_response(client_fd, response);
}
} else {
// Serve requested file
if (access(path + 1, F_OK) != -1) {
serve_file(client_fd, path + 1); // Skip leading '/'
} else {
fprintf(log_file, "404: File not found: %s\n", path);
char response[MAXLINE];
sprintf(response, "HTTP/1.1 404 Not Found\r\n"
"Content-Type: text/plain\r\n"
"\r\n"
"404 Not Found: File not found");
send_response(client_fd, response);
}
}
} else {
fprintf(log_file, "Unsupported method: %s\n", method);
char response[MAXLINE];
sprintf(response, "HTTP/1.1 501 Not Implemented\r\n"
"Content-Type: text/plain\r\n"
"\r\n"
"501 Not Implemented: Unsupported request method");
send_response(client_fd, response);
}
}
int main() {
// Initialize logging
init_log(“server.log”);
int server_fd, client_fd;
struct sockaddr_in server_addr, client_addr;
socklen_t client_addr_len = sizeof(client_addr);
server_fd = socket(AF_INET, SOCK_STREAM, 0);
if (server_fd < 0) {
perror("Error creating socket");
close_log();
exit(EXIT_FAILURE);
}
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = INADDR_ANY;
server_addr.sin_port = htons(PORT);
if (bind(server_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
perror("Error binding socket");
close(server_fd);
close_log();
exit(EXIT_FAILURE);
}
if (listen(server_fd, 10) < 0) {
perror("Error listening on socket");
close(server_fd);
close_log();
exit(EXIT_FAILURE);
}
fprintf(log_file, "Server listening on port %d\n", PORT);
while (1) {
client_fd = accept(server_fd, (struct sockaddr *)&client_addr, &client_addr_len);
if (client_fd < 0) {
perror("Error accepting connection");
continue;
}
fprintf(log_file, "Connection accepted from %s\n", inet_ntoa(client_addr.sin_addr));
handle_request(client_fd);
close(client_fd);
}
// Cleanup
close(server_fd);
close_log();
return 0;
}
优雅关闭
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
FILE *file = NULL; // 全局文件指针
void cleanup() {
if (file) {
fclose(file);
printf(“File closed successfully.\n”);
}
}
void signal_handler(int sig) {
if (sig == SIGINT) {
printf(“Caught signal %d, exiting…\n”, sig);
cleanup();
exit(0);
}
}
int main() {
// 设置信号处理器
signal(SIGINT, signal_handler);
// 打开文件
file = fopen("example.txt", "w");
if (file == NULL) {
perror("Failed to open file");
exit(EXIT_FAILURE);
}
// 主服务循环
while (1) {
fprintf(file, "Service is running...\n");
fflush(file);
sleep(1); // 模拟服务运行
}
// 正常退出前的清理
cleanup();
return 0;
}
time
#include <stdio.h>
#include <time.h>
int main() {
FILE *file;
time_t now;
struct tm *tm_info;
// 打开文件
file = fopen("server.log", "a"); // 以追加模式打开文件
if (file == NULL) {
perror("Error opening file");
return 1;
}
// 获取当前时间
time(&now);
tm_info = localtime(&now);
// 打印当前时间到文件
fprintf(file, "Current time: %s", asctime(tm_info));
// 关闭文件
fclose(file);
return 0;
}