服务端
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <pthread.h>
#define PORT 8080
#define BUFFER_SIZE 1024
void *connection_handler(void *socket_desc) {
int sock = *(int *)socket_desc;
char buffer[BUFFER_SIZE] = {0};
char *response = “HTTP/1.1 200 OK\nContent-Type: text/html\n\n
Hello, World!
\n”;read(sock, buffer, BUFFER_SIZE);
printf("Received request:\n%s\n", buffer);
write(sock, response, strlen(response));
close(sock);
free(socket_desc);
return NULL;
}
int main() {
int server_fd, new_socket;
struct sockaddr_in address;
int addrlen = sizeof(address);
// Create socket file descriptor
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
perror("socket failed");
exit(EXIT_FAILURE);
}
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(PORT);
// Bind socket to localhost:PORT
if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
perror("bind failed");
exit(EXIT_FAILURE);
}
// Listen for incoming connections
if (listen(server_fd, 3) < 0) {
perror("listen failed");
exit(EXIT_FAILURE);
}
printf("Server listening on port %d\n", PORT);
// Accept incoming connections and handle them using threads
while (1) {
if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t *)&addrlen)) < 0) {
perror("accept failed");
exit(EXIT_FAILURE);
}
printf("Connection accepted\n");
pthread_t thread;
int *new_sock = malloc(1);
*new_sock = new_socket;
if (pthread_create(&thread, NULL, connection_handler, (void *)new_sock) < 0) {
perror("could not create thread");
return 1;
}
// Detach the thread, so it will clean up after itself
pthread_detach(thread);
}
return 0;
}
完善客户请求处理
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/stat.h>
#include <fcntl.h>
#define PORT 8080
#define BUFFER_SIZE 1024
void send_response(int socket, int status, char* content_type, char* content) {
char response[BUFFER_SIZE] = {0};
char headers[BUFFER_SIZE] = {0};
sprintf(headers, "HTTP/1.1 %d ", status);
switch(status) {
case 200:
strcat(headers, "OK\r\n");
break;
case 404:
strcat(headers, "Not Found\r\n");
break;
default:
strcat(headers, "Internal Server Error\r\n");
}
sprintf(response, "%sContent-Type: %s\r\n\r\n%s", headers, content_type, content);
send(socket, response, strlen(response), 0);
}
void handle_request(int new_socket) {
char buffer[BUFFER_SIZE] = {0};
char method[10], path[255], protocol[20];
read(new_socket, buffer, BUFFER_SIZE);
sscanf(buffer, "%s %s %s", method, path, protocol);
if(strcmp(method, "GET") == 0) {
char file_path[255] = {0};
sprintf(file_path, ".%s", path);
// Open requested file
int fd = open(file_path, O_RDONLY);
if(fd == -1) {
send_response(new_socket, 404, "text/html", "<h1>404 Not Found</h1>");
} else {
struct stat file_stat;
fstat(fd, &file_stat);
char* content_type = "text/html";
if (strstr(file_path, ".png")) content_type = "image/png";
if (strstr(file_path, ".jpg")) content_type = "image/jpeg";
if (strstr(file_path, ".gif")) content_type = "image/gif";
if (strstr(file_path, ".html")) content_type = "text/html";
char* content = malloc(file_stat.st_size);
read(fd, content, file_stat.st_size);
send_response(new_socket, 200, content_type, content);
free(content);
}
} else {
send_response(new_socket, 500, "text/html", "<h1>500 Internal Server Error</h1>");
}
close(new_socket);
}
int main() {
int server_fd, new_socket;
struct sockaddr_in address;
int addrlen = sizeof(address);
// Creating socket file descriptor
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
perror("Socket creation failed");
exit(EXIT_FAILURE);
}
// Forcefully attaching socket to the port 8080
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(PORT);
// Binding socket to the specified port
if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
perror("Bind failed");
exit(EXIT_FAILURE);
}
// Listening for incoming connections
if (listen(server_fd, 3) < 0) {
perror("Listen failed");
exit(EXIT_FAILURE);
}
printf("Server listening on port %d\n", PORT);
// Accept incoming connections
while (1) {
if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) {
perror("Accept failed");
exit(EXIT_FAILURE);
}
// Handle incoming request
handle_request(new_socket);
}
return 0;
}
第三版
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>
#define PORT 8080
#define BUFFER_SIZE 1024
void send_response(int socket, int status, char* content_type, char* content) {
char response[BUFFER_SIZE] = {0};
char headers[BUFFER_SIZE] = {0};
sprintf(headers, "HTTP/1.1 %d ", status);
switch(status) {
case 200:
strcat(headers, "OK\r\n");
break;
case 404:
strcat(headers, "Not Found\r\n");
break;
default:
strcat(headers, "Internal Server Error\r\n");
}
sprintf(response, "%sContent-Type: %s\r\n\r\n%s", headers, content_type, content);
send(socket, response, strlen(response), 0);
}
void* handle_request(void* socket_ptr) {
int new_socket = ((int) socket_ptr);
char buffer[BUFFER_SIZE] = {0};
char method[10], path[255], protocol[20];
read(new_socket, buffer, BUFFER_SIZE);
sscanf(buffer, "%s %s %s", method, path, protocol);
if(strcmp(method, "GET") == 0) {
char file_path[255] = {0};
sprintf(file_path, ".%s", path);
// Open requested file
int fd = open(file_path, O_RDONLY);
if(fd == -1) {
send_response(new_socket, 404, "text/html", "<h1>404 Not Found</h1>");
} else {
struct stat file_stat;
fstat(fd, &file_stat);
char* content_type = "text/html";
if (strstr(file_path, ".png")) content_type = "image/png";
if (strstr(file_path, ".jpg")) content_type = "image/jpeg";
if (strstr(file_path, ".gif")) content_type = "image/gif";
if (strstr(file_path, ".html")) content_type = "text/html";
char* content = malloc(file_stat.st_size);
read(fd, content, file_stat.st_size);
send_response(new_socket, 200, content_type, content);
free(content);
}
} else {
send_response(new_socket, 500, "text/html", "<h1>500 Internal Server Error</h1>");
}
close(new_socket);
free(socket_ptr);
return NULL;
}
int main() {
int server_fd, new_socket;
struct sockaddr_in address;
int addrlen = sizeof(address);
// Creating socket file descriptor
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
perror("Socket creation failed");
exit(EXIT_FAILURE);
}
// Forcefully attaching socket to the port 8080
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(PORT);
// Binding socket to the specified port
if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
perror("Bind failed");
exit(EXIT_FAILURE);
}
// Listening for incoming connections
if (listen(server_fd, 3) < 0) {
perror("Listen failed");
exit(EXIT_FAILURE);
}
printf("Server listening on port %d\n", PORT);
// Accept incoming connections and handle in separate threads
while (1) {
if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) {
perror("Accept failed");
exit(EXIT_FAILURE);
}
// Create a new thread to handle the client
pthread_t thread;
int* socket_ptr = malloc(sizeof(int));
*socket_ptr = new_socket;
if (pthread_create(&thread, NULL, handle_request, (void*) socket_ptr) != 0) {
perror("Thread creation failed");
exit(EXIT_FAILURE);
}
pthread_detach(thread); // Detach the thread to avoid memory leaks
}
return 0;
}
修改
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#define PORT 12345
#define MAX_BUFFER_SIZE 1024
void send_data(int sockfd, const char *data) {
size_t total_sent = 0;
size_t data_len = strlen(data);
while (total_sent < data_len) {
ssize_t sent = send(sockfd, data + total_sent, data_len - total_sent, 0);
if (sent == -1) {
perror("send");
exit(EXIT_FAILURE);
}
total_sent += sent;
}
}
int main() {
int sockfd;
struct sockaddr_in server_addr;
const char *content = “This is the content to be sent to the socket.”;
// 创建socket
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket");
exit(EXIT_FAILURE);
}
// 设置server_addr结构
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(PORT);
server_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); // 替换为目标服务器的IP地址
// 连接到服务器
if (connect(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) {
perror("connect");
exit(EXIT_FAILURE);
}
// 发送数据
send_data(sockfd, content);
// 关闭socket
close(sockfd);
return 0;
}
加入post处理
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define PORT 8080
#define MAX_THREADS 5
void *connection_handler(void *socket_desc);
int main() {
int server_fd, new_socket, c;
struct sockaddr_in address, client_addr;
int opt = 1;
int addrlen = sizeof(address);
// Creating socket file descriptor
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
perror("socket failed");
exit(EXIT_FAILURE);
}
// Forcefully attaching socket to the port 8080
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) {
perror("setsockopt");
exit(EXIT_FAILURE);
}
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(PORT);
// Bind the socket to localhost port 8080
if (bind(server_fd, (struct sockaddr *)&address, sizeof(address))<0) {
perror("bind failed");
exit(EXIT_FAILURE);
}
// Try to specify maximum of 3 pending connections for the master socket
if (listen(server_fd, 3) < 0) {
perror("listen");
exit(EXIT_FAILURE);
}
printf("Server listening on port %d...\n", PORT);
// Accept incoming connections
while ((new_socket = accept(server_fd, (struct sockaddr *)&client_addr, (socklen_t*)&addrlen))) {
pthread_t thread;
int *new_sock = malloc(1);
*new_sock = new_socket;
if (pthread_create(&thread, NULL, connection_handler, (void*)new_sock) < 0) {
perror("could not create thread");
return 1;
}
// Now join the thread, so that we don't terminate before the thread
pthread_join(thread, NULL);
}
if (new_socket < 0) {
perror("accept failed");
return 1;
}
return 0;
}
void *connection_handler(void *socket_desc) {
// Get the socket descriptor
int sock = (int)socket_desc;
int read_size;
char client_message[1024];
char response[1024] = “HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n
Hello, World!
”;// Receive a message from client
read_size = recv(sock, client_message, 1024, 0);
if (read_size > 0) {
// Send the message back to client
write(sock, response, strlen(response));
}
free(socket_desc);
close(sock);
pthread_exit(NULL);
}
post请求处理
void *connection_handler(void *socket_desc) {
// Get the socket descriptor
int sock = (int)socket_desc;
int read_size;
char client_message[1024];
char response[1024];
// Receive a message from client
read_size = recv(sock, client_message, 1024, 0);
if (read_size > 0) {
// Parse HTTP request to get method and URI
char method[10], uri[50];
sscanf(client_message, "%s %s", method, uri);
// Check if it's a POST request
if (strcmp(method, "POST") == 0) {
// Find where the POST data begins
char *data_start = strstr(client_message, "\r\n\r\n");
if (data_start) {
// Move to actual data
data_start += 4;
// Example: Parse POST data (here assuming it's form-urlencoded)
char post_data[1024];
sscanf(data_start, "%s", post_data);
// Generate a response based on received data
sprintf(response, "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<html><body><h1>Hello, World! This is a POST request</h1><p>Received data: %s</p></body></html>", post_data);
} else {
// Malformed POST request (no data found)
sprintf(response, "HTTP/1.1 400 Bad Request\r\nContent-Type: text/plain\r\n\r\nBad Request");
}
} else {
// Handle other HTTP methods (not implemented in this example)
sprintf(response, "HTTP/1.1 405 Method Not Allowed\r\nContent-Type: text/plain\r\n\r\nMethod Not Allowed");
}
// Send the message back to client
write(sock, response, strlen(response));
}
free(socket_desc);
close(sock);
pthread_exit(NULL);
}
传输图像
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#define PORT 8080
#define BUFFER_SIZE 1024
void send_image(int client_socket, const char *filename) {
FILE *fp = fopen(filename, “rb”);
if (fp == NULL) {
perror(“Error opening file”);
return;
}
fseek(fp, 0, SEEK_END);
long file_size = ftell(fp);
rewind(fp);
// 构建 HTTP 头部
char header[BUFFER_SIZE];
snprintf(header, sizeof(header),
"HTTP/1.1 200 OK\r\n"
"Content-Type: image/jpeg\r\n"
"Content-Length: %ld\r\n\r\n", file_size);
// 发送 HTTP 头部
send(client_socket, header, strlen(header), 0);
// 发送图像数据
char buffer[BUFFER_SIZE];
size_t bytes_read;
while ((bytes_read = fread(buffer, 1, BUFFER_SIZE, fp)) > 0) {
send(client_socket, buffer, bytes_read, 0);
}
fclose(fp);
}
int main() {
int server_fd, new_socket;
struct sockaddr_in address;
int addrlen = sizeof(address);
// 创建 socket
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
perror("Socket creation failed");
exit(EXIT_FAILURE);
}
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(PORT);
// 绑定地址和端口
if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
perror("Bind failed");
exit(EXIT_FAILURE);
}
// 监听连接
if (listen(server_fd, 10) < 0) {
perror("Listen failed");
exit(EXIT_FAILURE);
}
printf("Server listening on port %d\n", PORT);
while (1) {
// 接受连接
if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t *)&addrlen)) < 0) {
perror("Accept failed");
exit(EXIT_FAILURE);
}
// 接收客户端请求
char buffer[BUFFER_SIZE] = {0};
read(new_socket, buffer, BUFFER_SIZE);
// 提取请求中的文件名
char *filename = "example.jpg"; // 修改为实际的图片文件名
printf("Requested file: %s\n", filename);
// 发送图片
send_image(new_socket, filename);
// 关闭连接
close(new_socket);
}
return 0;
}
使用文件描述符
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <fcntl.h>
#define PORT 8080
#define BUFFER_SIZE 1024
void send_image(int client_fd, const char *filename) {
int file_fd = open(filename, O_RDONLY);
if (file_fd < 0) {
perror(“Error opening file”);
return;
}
// 获取文件大小
off_t file_size = lseek(file_fd, 0, SEEK_END);
lseek(file_fd, 0, SEEK_SET);
// 构建 HTTP 头部
char header[BUFFER_SIZE];
snprintf(header, sizeof(header),
"HTTP/1.1 200 OK\r\n"
"Content-Type: image/jpeg\r\n"
"Content-Length: %ld\r\n\r\n", (long)file_size);
// 发送 HTTP 头部
write(client_fd, header, strlen(header));
// 发送图像数据
char buffer[BUFFER_SIZE];
ssize_t bytes_read;
while ((bytes_read = read(file_fd, buffer, BUFFER_SIZE)) > 0) {
write(client_fd, buffer, bytes_read);
}
close(file_fd);
}
int main() {
int server_fd, new_socket;
struct sockaddr_in address;
int addrlen = sizeof(address);
// 创建 socket
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
perror("Socket creation failed");
exit(EXIT_FAILURE);
}
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(PORT);
// 绑定地址和端口
if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
perror("Bind failed");
exit(EXIT_FAILURE);
}
// 监听连接
if (listen(server_fd, 10) < 0) {
perror("Listen failed");
exit(EXIT_FAILURE);
}
printf("Server listening on port %d\n", PORT);
while (1) {
// 接受连接
if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t *)&addrlen)) < 0) {
perror("Accept failed");
exit(EXIT_FAILURE);
}
// 接收客户端请求
char buffer[BUFFER_SIZE] = {0};
read(new_socket, buffer, BUFFER_SIZE);
// 提取请求中的文件名
char *filename = "example.jpg"; // 修改为实际的图片文件名
printf("Requested file: %s\n", filename);
// 发送图片
send_image(new_socket, filename);
// 关闭连接
close(new_socket);
}
return 0;
}