做教育网站需要规划哪些内容,网站开发岗位,购物网站建设实战教程答案,专业自适应网站建设极速建站系列目录
上一篇#xff1a;白骑士的C教学实战项目篇 4.2 学生成绩管理系统 在这一节中#xff0c;我们将实现一个多线程网络服务器项目#xff0c;通过该项目#xff0c;我们将学习套接字编程的基础知识以及如何使用多线程处理并发连接。此外#xff0c;我们还将实现一个…系列目录
上一篇白骑士的C教学实战项目篇 4.2 学生成绩管理系统 在这一节中我们将实现一个多线程网络服务器项目通过该项目我们将学习套接字编程的基础知识以及如何使用多线程处理并发连接。此外我们还将实现一个简单的客户端来与服务器进行通信。
项目简介 多线程网络服务器是一种可以同时处理多个客户端请求的服务器。通过多线程技术我们可以使服务器在处理一个客户端请求时不阻塞其他客户端的连接请求。本项目将涉及以下内容
套接字编程基础多线程处理客户端与服务器的实现
套接字编程基础 套接字Socket是网络编程的基础它提供了在网络上进行数据通信的机制。在C中我们可以使用POSIX标准库如 ‘sys/socket.h‘、‘arpa/inet.h‘ 等来进行套接字编程。下面是一个基本的服务器和客户端通信的示例。
服务器端代码
#include iostream
#include unistd.h
#include netinet/in.h
#include string.h
#include threadconst int PORT 8080;void handleClient(int clientSocket) {char buffer[1024] {0};read(clientSocket, buffer, 1024);std::cout Message from client: buffer std::endl;send(clientSocket, buffer, strlen(buffer), 0);close(clientSocket);
}int main() {int serverFd, clientSocket;struct sockaddr_in address;int opt 1;int addrlen sizeof(address);// 创建服务器端套接字if ((serverFd socket(AF_INET, SOCK_STREAM, 0)) 0) {perror(socket failed);exit(EXIT_FAILURE);}// 设置套接字选项if (setsockopt(serverFd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, opt, sizeof(opt))) {perror(setsockopt failed);exit(EXIT_FAILURE);}address.sin_family AF_INET;address.sin_addr.s_addr INADDR_ANY;address.sin_port htons(PORT);// 绑定套接字if (bind(serverFd, (struct sockaddr*)address, sizeof(address)) 0) {perror(bind failed);exit(EXIT_FAILURE);}// 监听连接if (listen(serverFd, 3) 0) {perror(listen failed);exit(EXIT_FAILURE);}while (true) {std::cout Waiting for connections...\n;if ((clientSocket accept(serverFd, (struct sockaddr*)address, (socklen_t*)addrlen)) 0) {perror(accept failed);exit(EXIT_FAILURE);}std::thread clientThread(handleClient, clientSocket);clientThread.detach(); // 将线程分离以便独立运行}close(serverFd);return 0;
}
客户端代码
#include iostream
#include unistd.h
#include arpa/inet.h
#include string.hconst int PORT 8080;int main() {int sock 0;struct sockaddr_in serv_addr;char* message Hello from client;char buffer[1024] {0};// 创建客户端套接字if ((sock socket(AF_INET, SOCK_STREAM, 0)) 0) {std::cerr Socket creation error std::endl;return -1;}serv_addr.sin_family AF_INET;serv_addr.sin_port htons(PORT);// 将IP地址转换为二进制格式if (inet_pton(AF_INET, 127.0.0.1, serv_addr.sin_addr) 0) {std::cerr Invalid address/ Address not supported std::endl;return -1;}// 连接服务器if (connect(sock, (struct sockaddr*)serv_addr, sizeof(serv_addr)) 0) {std::cerr Connection failed std::endl;return -1;}send(sock, message, strlen(message), 0);std::cout Message sent std::endl;read(sock, buffer, 1024);std::cout Message from server: buffer std::endl;close(sock);return 0;
}
多线程处理 在上述服务器代码中我们使用了 ‘std::thread‘ 来为每个客户端连接创建一个新线程并使用 ‘detach‘ 将其分离使线程能够独立运行而不阻塞主线程。这种方式可以有效地处理多个客户端的并发连接。
客户端与服务器的实现 我们已经实现了基本的客户端和服务器通信。为了使系统更健壮可以考虑添加以下功能
异常处理处理各种可能的网络异常如连接失败、读写失败等。日志记录记录客户端连接和断开时间、传输的数据等信息。并发控制限制同时连接的客户端数量防止服务器过载。
完整代码示例
#include iostream#include unistd.h#include netinet/in.h#include string.h
#include thread
#include vector
#include mutexconst int PORT 8080;std::mutex coutMutex;void handleClient(int clientSocket) {char buffer[1024] {0};read(clientSocket, buffer, 1024);{std::lock_guardstd::mutex lock(coutMutex);std::cout Message from client: buffer std::endl;}send(clientSocket, buffer, strlen(buffer), 0);close(clientSocket);
}int main() {int serverFd, clientSocket;struct sockaddr_in address;int opt 1;int addrlen sizeof(address);// 创建服务器端套接字if ((serverFd socket(AF_INET, SOCK_STREAM, 0)) 0) {perror(socket failed);exit(EXIT_FAILURE);}// 设置套接字选项if (setsockopt(serverFd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, opt, sizeof(opt))) {perror(setsockopt failed);exit(EXIT_FAILURE);}address.sin_family AF_INET;address.sin_addr.s_addr INADDR_ANY;address.sin_port htons(PORT);// 绑定套接字if (bind(serverFd, (struct sockaddr*)address, sizeof(address)) 0) {perror(bind failed);exit(EXIT_FAILURE);}// 监听连接if (listen(serverFd, 3) 0) {perror(listen failed);exit(EXIT_FAILURE);}while (true) {std::cout Waiting for connections...\n;if ((clientSocket accept(serverFd, (struct sockaddr*)address, (socklen_t*)addrlen)) 0) {perror(accept failed);exit(EXIT_FAILURE);}std::thread clientThread(handleClient, clientSocket);clientThread.detach();}close(serverFd);return 0;
} 通过以上代码我们实现了一个简单的多线程网络服务器能够同时处理多个客户端的连接请求。这个项目不仅帮助我们掌握了套接字编程的基础知识还了解了多线程处理的基本方法。
总结 多线程网络服务器项目使我们掌握了网络编程和多线程处理的基本知识。通过实践套接字编程和多线程技术我们可以开发出更高效、更稳定的网络应用程序。
下一篇白骑士的C教学附加篇 5.1 C开发工具