-
Notifications
You must be signed in to change notification settings - Fork 0
/
chatserver.h
70 lines (54 loc) · 1.76 KB
/
chatserver.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#pragma once
#include <arpa/inet.h>
#include <sys/epoll.h>
#include <unistd.h>
#include <iostream>
#include <memory>
#include <string>
#include <unordered_map>
#include "epoll.h"
// This structure represents a connected client.
class Client {
public:
explicit Client(int fd, sockaddr_in addr)
: fd_(fd), nick_("user:" + std::to_string(fd)), addr_(addr) {
std::cout << "accept client conn: " << GetAddrStr() << std::endl;
}
~Client() {
std::cout << "disconnected client conn: " << GetAddrStr() << std::endl;
close(fd_);
}
int GetFd() const { return fd_; }
const std::string &GetNick() const { return nick_; }
sockaddr_in GetAddr() const { return addr_; }
std::string GetAddrStr() const {
return std::string(inet_ntoa(addr_.sin_addr)) + ":" +
std::to_string(ntohs(addr_.sin_port));
}
private:
int fd_; // Client socket.
std::string nick_; // Nickname of the client.
sockaddr_in addr_; // Client addr
};
class ChatServer {
public:
ChatServer(int port);
~ChatServer();
void Run();
private:
// Create a TCP socket listening to 'port' ready to accept connections.
int CreateTCPServer(int port);
// If the listening socket is "readable", it actually means
// there are new clients connections pending to accept.
void AcceptClient(int fd);
// ReadAndBroadcast a well formed message from one client.
void ReadAndBroadcast(int fd);
void AddClient(std::shared_ptr<Client> client);
void RemoveClient(std::shared_ptr<Client> client);
// Send the specified string to all connected clients but the one
// having as socket descriptor 'excluded'.
void SendMsgToAllClientsBut(int excluded, const std::string &msg);
private:
Epoll epoll_;
std::unordered_map<int, std::shared_ptr<Client>> clients_;
};