2025-2026-1 20231301 《信息安全设计》第十一周学习总结
2025-2026-1 20231301 《信息安全设计》第十一周学习总结
作业信息
| 作业 | 链接 |
|---|---|
| 作业课程 | <班级>(2025-2026-1 信息安全设计) |
| 作业要求 | <作业>(2025-2026-1 信息安全设计 预习作业要求) |
| 作业目标 | 《Head First C 嗨翻C语⾔》> 预习第十一章 |
| 作业正文 | <博客>(第十一周学习总结) |
学习内容总结
第十一章:套接字与网络编程
网络编程核心概念
1. 套接字类型与协议
#include <sys/socket.h>
void socket_types_demo() {
// 流式套接字 (TCP)
int tcp_socket = socket(PF_INET, SOCK_STREAM, 0);
// 数据报套接字 (UDP)
int udp_socket = socket(PF_INET, SOCK_DGRAM, 0);
// 原始套接字 (直接IP访问)
int raw_socket = socket(PF_INET, SOCK_RAW, IPPROTO_RAW);
printf("TCP socket: %d\n", tcp_socket);
printf("UDP socket: %d\n", udp_socket);
close(tcp_socket);
close(udp_socket);
}
2. 完整的TCP服务器实现
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define PORT 8080
#define BUFFER_SIZE 1024
void tcp_echo_server() {
int server_fd, new_socket;
struct sockaddr_in address;
int opt = 1;
int addrlen = sizeof(address);
char buffer[BUFFER_SIZE] = {0};
// 创建套接字文件描述符
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
perror("socket failed");
exit(EXIT_FAILURE);
}
// 设置套接字选项
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &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);
// 绑定套接字到端口
if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
perror("bind failed");
exit(EXIT_FAILURE);
}
// 开始监听
if (listen(server_fd, 3) < 0) {
perror("listen");
exit(EXIT_FAILURE);
}
printf("Server listening on port %d\n", PORT);
while (1) {
printf("Waiting for connections...\n");
if ((new_socket = accept(server_fd, (struct sockaddr *)&address,
(socklen_t*)&addrlen)) < 0) {
perror("accept");
exit(EXIT_FAILURE);
}
printf("Connection accepted from %s:%d\n",
inet_ntoa(address.sin_addr), ntohs(address.sin_port));
// 读取客户端数据
ssize_t valread = read(new_socket, buffer, BUFFER_SIZE);
printf("Received: %s\n", buffer);
// 发送响应
const char* response = "Hello from server";
send(new_socket, response, strlen(response), 0);
printf("Response sent\n");
close(new_socket);
}
close(server_fd);
}
3. 高级客户端实现
#include <netdb.h>
int create_connected_socket(const char* hostname, const char* port) {
struct addrinfo hints, *result, *rp;
int sockfd;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC; // IPv4 或 IPv6
hints.ai_socktype = SOCK_STREAM; // TCP 套接字
// 解析主机名和服务名
int status = getaddrinfo(hostname, port, &hints, &result);
if (status != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(status));
return -1;
}
// 尝试每个地址直到成功连接
for (rp = result; rp != NULL; rp = rp->ai_next) {
sockfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
if (sockfd == -1)
continue;
if (connect(sockfd, rp->ai_addr, rp->ai_addrlen) != -1)
break; // 成功连接
close(sockfd); // 连接失败,关闭套接字继续尝试
}
freeaddrinfo(result);
if (rp == NULL) {
fprintf(stderr, "Could not connect to %s:%s\n", hostname, port);
return -1;
}
return sockfd;
}
void http_client_demo() {
int sockfd = create_connected_socket("www.example.com", "80");
if (sockfd == -1) return;
// 发送 HTTP 请求
const char* http_request =
"GET / HTTP/1.1\r\n"
"Host: www.example.com\r\n"
"Connection: close\r\n"
"\r\n";
if (send(sockfd, http_request, strlen(http_request), 0) == -1) {
perror("send");
close(sockfd);
return;
}
// 接收响应
char buffer[4096];
ssize_t bytes_received;
printf("HTTP Response:\n");
while ((bytes_received = recv(sockfd, buffer, sizeof(buffer)-1, 0)) > 0) {
buffer[bytes_received] = '\0';
printf("%s", buffer);
}
close(sockfd);
}
并发服务器架构
多进程并发服务器
void concurrent_server() {
int server_fd = socket(AF_INET, SOCK_STREAM, 0);
// ... 绑定和监听代码同上
while (1) {
int client_socket = accept(server_fd, NULL, NULL);
if (client_socket < 0) {
perror("accept");
continue;
}
pid_t pid = fork();
if (pid == 0) {
// 子进程
close(server_fd); // 子进程不需要监听套接字
handle_client(client_socket);
close(client_socket);
_exit(0);
} else if (pid > 0) {
// 父进程
close(client_socket); // 父进程不需要客户端套接字
} else {
perror("fork");
close(client_socket);
}
}
}
void handle_client(int client_socket) {
char buffer[1024];
ssize_t bytes_read;
// 处理客户端请求
while ((bytes_read = recv(client_socket, buffer, sizeof(buffer), 0)) > 0) {
// 处理数据...
send(client_socket, buffer, bytes_read, 0);
}
}
思维导图

posted on 2025-09-30 22:02 20231301周子昂 阅读(6) 评论(0) 收藏 举报
浙公网安备 33010602011771号