当前位置:实例文章 » 其他实例» [文章]TCP/IP网络编程 第五章:实现基于TCP的服务端/客户端(2)

TCP/IP网络编程 第五章:实现基于TCP的服务端/客户端(2)

发布人:shili8 发布时间:2025-01-03 02:59 阅读次数:0

**TCP/IP网络编程**

**第五章: 实现基于TCP的服务端/客户端(2)**在前一章中,我们已经实现了一个简单的基于TCP的服务端和客户端程序。然而,这个程序存在一些问题,例如:

*服务端无法处理多个客户端连接* 客户端无法同时发送多条消息给服务端为了解决这些问题,我们需要对服务端和客户端进行改进。

**5.1服务端改进**

首先,让我们来看看如何改进服务端。我们可以使用一个线程池来处理多个客户端连接,这样就可以避免由于多个线程竞争资源而导致的性能问题。

cpp#include <iostream>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>

#define PORT12345class Server {
public:
 Server() : _sockfd(-1), _threadPool(5) {}

 ~Server() { close(_sockfd); }

 void start() {
 // 创建套接字 _sockfd = socket(AF_INET, SOCK_STREAM,0);
 if (_sockfd < 0) {
 std::cerr << "socket error" << std::endl;
 return;
 }

 // 设置地址和端口号 struct sockaddr_in addr;
 addr.sin_family = AF_INET;
 addr.sin_port = htons(PORT);
 inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr);

 // 绑定套接字到指定的地址和端口号上 if (bind(_sockfd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
 std::cerr << "bind error" << std::endl;
 return;
 }

 // 监听套接字,等待连接请求 listen(_sockfd,5);

 while (true) {
 struct sockaddr_in clientAddr;
 socklen_t clientLen = sizeof(clientAddr);
 int clientSockfd = accept(_sockfd, (struct sockaddr*)&clientAddr, &clientLen);
 if (clientSockfd < 0) {
 std::cerr << "accept error" << std::endl;
 continue;
 }

 // 将客户端连接添加到线程池中 _threadPool.add(clientSockfd);

 // 等待线程池处理完成 _threadPool.wait();
 }
 }

private:
 int _sockfd;
 ThreadPool _threadPool;
};

class ThreadPool {
public:
 void add(int sockfd) { _threads.push_back(std::make_shared<Thread>(sockfd)); }

 void wait() {
 for (auto& thread : _threads) {
 thread->join();
 }
 _threads.clear();
 }

private:
 std::vector<std::shared_ptr<Thread>> _threads;
};

class Thread {
public:
 Thread(int sockfd) : _sockfd(sockfd), _running(false) {}

 void run() {
 if (!_running) {
 _running = true;

 // 处理客户端连接 while (true) {
 char buffer[1024];
 int len = recv(_sockfd, buffer,1024,0);
 if (len < 0) {
 break;
 }

 // 处理消息 std::string message(buffer, len);

 // 发送回复消息 send(_sockfd, message.c_str(), message.size(),0);
 }
 }
 }

private:
 int _sockfd;
 bool _running;
};


**5.2 客户端改进**

同样,我们需要对客户端进行改进,以便能够同时发送多条消息给服务端。

cpp#include <iostream>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>

#define PORT12345class Client {
public:
 Client() : _sockfd(-1) {}

 ~Client() { close(_sockfd); }

 void start() {
 // 创建套接字 _sockfd = socket(AF_INET, SOCK_STREAM,0);
 if (_sockfd < 0) {
 std::cerr << "socket error" << std::endl;
 return;
 }

 // 设置地址和端口号 struct sockaddr_in addr;
 addr.sin_family = AF_INET;
 addr.sin_port = htons(PORT);
 inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr);

 // 连接服务端 if (connect(_sockfd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
 std::cerr << "connect error" << std::endl;
 return;
 }

 while (true) {
 char buffer[1024];
 int len = recv(_sockfd, buffer,1024,0);
 if (len < 0) {
 break;
 }

 // 处理消息 std::string message(buffer, len);

 // 发送回复消息 send(_sockfd, message.c_str(), message.size(),0);
 }
 }

private:
 int _sockfd;
};


**5.3 总结**

在本章中,我们对服务端和客户端进行了改进,使得它们能够处理多个连接并同时发送多条消息。这些改进使得基于TCP的服务端/客户端程序更加高效和可靠。

然而,这些改进也带来了新的挑战,例如如何管理线程池、如何处理多个连接等问题。这些挑战需要我们深入研究网络编程的原理和技术,以便能够设计出高性能、高可靠性的服务端/客户端程序。

**参考**

* 《TCP/IP网络编程》第五章* 《Linux socket编程》第五章

其他信息

其他资源

Top