导航菜单

C++编程/项目实战
课程进度 103% · 第19/18章19/18章 · 标签 1/2
1

多人聊天室 — 服务器

使用 TCP 实现多人聊天室功能,综合运用 Socket、多线程和容器。

cpp
1
class ChatServer {
2
private:
3
int serverSocket;
4
vector<int> clientSockets;
5
mutex clientsMutex;
6
 
7
void broadcast(const string& message, int excludeSocket = -1) {
8
lock_guard<mutex> lock(clientsMutex);
9
for (int clientSocket : clientSockets) {
10
if (clientSocket != excludeSocket) {
11
send(clientSocket, message.c_str(), message.length(), 0);
12
}
13
}
14
}
15
 
16
void handleClient(int clientSocket) {
17
char buffer[1024];
18
string welcomeMsg = "欢迎加入聊天室!";
19
send(clientSocket, welcomeMsg.c_str(), welcomeMsg.length(), 0);
20
 
21
while (true) {
22
memset(buffer, 0, sizeof(buffer));
23
int bytesRead = recv(clientSocket, buffer, sizeof(buffer), 0);
24
 
25
if (bytesRead <= 0) {
26
{
27
lock_guard<mutex> lock(clientsMutex);
28
auto it = find(clientSockets.begin(), clientSockets.end(), clientSocket);
29
if (it != clientSockets.end()) clientSockets.erase(it);
30
}
31
broadcast("一个用户离开了聊天室", clientSocket);
32
close(clientSocket);
33
break;
34
}
35
broadcast(string(buffer), clientSocket);
36
}
37
}
2

服务器主循环

cpp
1
public:
2
ChatServer(int port) {
3
serverSocket = socket(AF_INET, SOCK_STREAM, 0);
4
if (serverSocket == -1) throw runtime_error("创建socket失败");
5
 
6
sockaddr_in serverAddr;
7
serverAddr.sin_family = AF_INET;
8
serverAddr.sin_port = htons(port);
9
serverAddr.sin_addr.s_addr = INADDR_ANY;
10
 
11
if (bind(serverSocket, (struct sockaddr*)&serverAddr, sizeof(serverAddr)) < 0)
12
throw runtime_error("绑定失败");
13
if (listen(serverSocket, 5) < 0)
14
throw runtime_error("监听失败");
15
}
16
 
17
void start() {
18
cout << "聊天室服务器已启动..." << endl;
19
while (true) {
20
sockaddr_in clientAddr;
21
socklen_t clientLen = sizeof(clientAddr);
22
int clientSocket = accept(serverSocket, (struct sockaddr*)&clientAddr, &clientLen);
23
if (clientSocket < 0) continue;
24
 
25
{
26
lock_guard<mutex> lock(clientsMutex);
27
clientSockets.push_back(clientSocket);
28
}
29
thread(&ChatServer::handleClient, this, clientSocket).detach();
30
}
31
}
32
};

📖本项目综合了 Socket 编程、多线程(每个客户端一个线程)、mutex 同步、STL 容器等核心技术