content_1721281806352.zip
立即下载
资源介绍:
content_1721281806352.zip
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define SERVER_CERT "/home/zjyubuntu2004/05-http_server/keys/cnlab.cert"
#define SERVER_KEY "/home/zjyubuntu2004/05-http_server/keys/cnlab.prikey"
#define SERVER_PORT 443
#define PORT 80
#define SERVER_IP "10.0.0.1"
//#define VIDEO_FILE "/home/zjyubuntu2004/mininet/1.mp4"
int request_count = 0;
void *handle_client(void *arg);
void *handle_clients(void *args);
int flag=0;
int main() {
/*int server_fd, client_socket;
struct sockaddr_in server_addr, client_addr;
socklen_t client_addr_size;*/
int server_sockets, client_sockets=0;
int server_fd, client_socket=0;
struct sockaddr_in server_addr, client_addr,server_addrs, client_addrs;
socklen_t client_addr_size;
// 创建套接字
server_fd = socket(AF_INET, SOCK_STREAM, 0);
if (server_fd < 0)
{
perror("Socket creation failed");
exit(EXIT_FAILURE);
}
// 定义服务器地址
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = inet_addr(SERVER_IP);
server_addr.sin_port = htons(PORT);
// 绑定套接字
if (bind(server_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0)
{
perror("Bind failed");
exit(EXIT_FAILURE);
}
// 监听套接字
if (listen(server_fd, 10) < 0)
{
perror("Listen failed");
exit(EXIT_FAILURE);
}
printf("HTTP Server running on port %d\n", PORT);
socklen_t client_lens = sizeof(client_addrs);
// 初始化SSL库
SSL_load_error_strings();
SSL_library_init();
// 创建套接字
server_sockets = socket(AF_INET, SOCK_STREAM, 0);
if (server_sockets < 0)
{
perror("套接字创建失败");
return EXIT_FAILURE;
}
// 设置服务器地址
memset(&server_addrs, 0, sizeof(server_addrs));
server_addrs.sin_family = AF_INET;
server_addrs.sin_addr.s_addr = inet_addr(SERVER_IP);
server_addrs.sin_port = htons(SERVER_PORT);
// 绑定服务器地址
if (bind(server_sockets, (struct sockaddr*)&server_addrs, sizeof(server_addrs)) < 0)
{
perror("绑定失败");
close(server_sockets);
return EXIT_FAILURE;
}
// 监听端口
if (listen(server_sockets, 5) < 0)
{
perror("监听失败");
close(server_sockets);
return EXIT_FAILURE;
}
printf("HTTP Server running on port %d\n", SERVER_PORT);
int flag1=0;
int flag2=0;
while(1)
{
while (1)
{
//80端口接受客户端连接
client_addr_size = sizeof(client_addr);
client_socket = accept(server_fd, (struct sockaddr *)&client_addr, &client_addr_size);
printf("client_socket=%d",client_socket);
if (client_socket < 0){
perror("Accept failed");
continue;
}
//80端口创建线程处理客户端请求
pthread_t tid;
if (pthread_create(&tid, NULL, handle_client, (void *)&client_socket) != 0)
{
perror("Thread creation failed");
close(client_socket);
}
if(flag=-1)
{
flag1++;
printf("flag1=%d",flag1);
break;
}
}
// 443端口接受客户端连接
if(flag1==1)
{
client_sockets = accept(server_sockets, (struct sockaddr*)&client_addrs, &client_lens);
printf("client_sockets=%d\n",client_sockets);
if (client_sockets < 0)
{
perror("连接接受失败");
continue;
}
pthread_t tid2;
if (pthread_create(&tid2, NULL, handle_clients, (void*)&client_sockets) != 0)
{
perror("线程创建失败");
close(client_sockets);
}
if(flag=-1)
{
pthread_detach(tid2);
flag1++;
printf("flag1=%d",flag1);
}
}
}
// 关闭服务器套接字
return 0;
}
void *handle_client(void *arg) {
flag=0;
int client_socket = *((int *)arg);
char buffer[1024];
int file_fd, n;
request_count++;
// 读取客户端请求
read(client_socket, buffer, 1024);
printf("Received data from client: %s\n", buffer);
char filename[256];
if (sscanf(buffer, "GET %255s", filename) == 1) {
printf("Filename: %s\n", filename);
} else {
printf("Failed to extract filename\n");
}
char path[1024] = {0};
sprintf(path,"/home/zjyubuntu2004/mininet%s",filename);
printf("path=%s\n",path);
file_fd = open(path, O_RDONLY);
// 检查是否为mp4请求
if (strstr(buffer, "mp4") != NULL) {
// 打开视频文件
if (file_fd < 0) {
perror("File open failed");
return NULL;
}
// 发送HTTP响应头
write(client_socket, "HTTP/1.1 200 OK\r\n", 17);
write(client_socket, "Content-Type: video/mp4\r\n\r\n", 27);
// 发送视频文件内容
while ((n = read(file_fd, buffer, 1024)) > 0) {
write(client_socket, buffer, n);
}
flag=-1;
close(file_fd);
}
else{
//文件不存在,返回404
if(file_fd == -1)
{
write(client_socket,"HTTP/1.1 404 Not FOUND\n\n",24);//响应头
write(client_socket,"Resource Not Found!
",28);//响应体
shutdown(client_socket,SHUT_RDWR);
flag=-1;
pthread_exit(NULL);
}
//是否包含 Range 头
if (strstr(buffer, "Range: bytes=") != NULL)
{
int start, end;
const char* rangeText = "Range: bytes=";
char* rangeStart = strstr(buffer, rangeText);
if (rangeStart != NULL)
{
rangeStart += strlen(rangeText); // 移动指针到 Range 值的起始位置
sscanf(rangeStart, "%d-%d", &start, &end) ;
printf("Range start: %d\n", start);
printf("Range end: %d\n", end-start);}
// 如果包含 Range 头,输出相应的逻辑
write(client_socket,"HTTP/1.1 206 Range\n\n",20);//响应头
const char* file_path = path;
FILE* file = fopen(file_path, "rb");
if (file == NULL) // 错误处理
{
printf("Failed to open file: %s\n", file_path);
exit(1);
}
// 移动文件指针到第100个字节的位置
if (fseek(file, 100, SEEK_SET) != 0)// 移动文件指针到第100个字节的位置
{
printf("Failed to seek file pointer\n");// 错误处理
fclose(file);
exit(1);
}
// 读取长度为102个字节的内容到缓冲区
if(end-start > 0)
{
char b