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 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
| #include<iostream> #include<mutex> #include<thread> #include<arpa/inet.h> #include<sys/socket.h> #include<netinet/in.h> #include<vector> #include<queue> #include<errno.h> #include<cstring> #include<unistd.h> using std::vector; using std::queue; using std::thread;
struct msg_struct { int sockfd; std::string msg; };
struct socket_struct { int socketcli; std::string cliip; };
int client_count = 0; std::mutex mtx; vector<thread> threads; vector<socket_struct> socket_vector; queue<msg_struct> msg_queue;
struct ip_hdr { u_char ip_ver:4, ip_hlen:4; u_char tos; u_short total_len; u_short id; u_short flags_offset; u_char ttl; u_char protocol; u_short checksum; in_addr srcip; in_addr desip; };
std::string get_ip(int sock) { for (int i = 0; i < client_count; i++) { if (socket_vector[i].socketcli == sock) { return socket_vector[i].cliip; } } return ""; }
void forwardmsg() { int ret = 0; while (true) { std::lock_guard<std::mutex> lock(mtx); if (msg_queue.empty()) { continue; } else if (msg_queue.front().msg == "0x02") { msg_queue.pop(); continue; }
int sendsock = msg_queue.front().sockfd; std::string send_msg = get_ip(sendsock) + " send: " + msg_queue.front().msg; msg_queue.pop();
const char* msgchar = send_msg.c_str(); int msglen = send_msg.length(); std::cout << send_msg << "\n"; for (int i = 0; i < client_count; i++) { if(socket_vector[i].socketcli != sendsock) { ret = send(socket_vector[i].socketcli, msgchar, msglen, 0); if (ret < 0) { printf("send failed, error code: %d", errno); } else { printf("%d socket sent success.\n", socket_vector[i].socketcli); } } } } }
void welcome_msg(std::string buf, int clisock) { for (int i = 0; i < client_count; i++) { if(socket_vector[i].socketcli != clisock) { send(socket_vector[i].socketcli, buf.c_str(), sizeof(buf), 0); } } }
void bye_msg(std::string byemsg, int clisock) { for (int i = 0; i < client_count; i++) { if(socket_vector[i].socketcli != clisock) { send(socket_vector[i].socketcli, byemsg.c_str(), sizeof(byemsg), 0); } } }
void sockethandler(int socketcli) { int ret; char buf[256]; int buflen = sizeof(buf);
while (true) { memset(buf, 0, buflen); ret = recv(socketcli, &buf, buflen, 0); if (ret < 0) { printf("recv failed, error code: %d", errno); continue; } else if (ret > 0) { std::lock_guard<std::mutex> lock(mtx); printf("recv from %d, message: %s \n", socketcli, buf); msg_struct recvmsg; recvmsg.msg = buf; recvmsg.sockfd = socketcli; msg_queue.push(recvmsg); } else { std::lock_guard<std::mutex> lock(mtx); if (msg_queue.front().msg == "0x02" || ret == 0) { std::string byemsg = get_ip(socketcli) + " quit..."; bye_msg(byemsg, socketcli); } std::vector<socket_struct>::iterator itr = socket_vector.begin(); while (itr != socket_vector.end()) { if ((*itr).socketcli == socketcli) { itr = socket_vector.erase(itr); break; } else { ++itr; } } client_count--; } } }
int main() { int socket_server = socket(AF_INET, SOCK_STREAM, IPPROTO_IP); if (socket_server <=0) { printf("socket_server created failed, error code: %d", errno); }
sockaddr_in addr_server; addr_server.sin_addr.s_addr = INADDR_ANY; addr_server.sin_family = AF_INET; addr_server.sin_port = htons(11451); int addr_server_len = sizeof(addr_server);
int ref; ref = bind(socket_server, (sockaddr*)&addr_server, addr_server_len); if (ref < 0) printf("socket_server bind faild, error code: %d \n", errno);
ref = listen(socket_server, 5); if (ref < 0) printf("socket_server listen failed, error code: %d \n", errno);
thread forwardthread(forwardmsg);
int socket_client; while (client_count < 5) { socket_struct sockfd; ref = socket_client = accept(socket_server, (sockaddr*)&addr_server, (socklen_t*)&addr_server_len); if (ref <= 0) { printf("accept failed, error code: %d \n", errno); continue; }
char cliip[INET_ADDRSTRLEN]; inet_ntop(AF_INET, &addr_server.sin_addr, cliip, INET_ADDRSTRLEN); sockfd.socketcli = socket_client; sockfd.cliip = cliip; socket_vector.push_back(sockfd); std:: cout << "connect from: " << sockfd.cliip << " , socket num: " << sockfd.socketcli << std::endl; std::string welcome = sockfd.cliip + " connect to the server."; welcome_msg(welcome, sockfd.socketcli); threads.emplace_back([socket_client]() {sockethandler(socket_client);}); client_count++; }
for (auto& thread : threads) thread.join();
close(socket_server); return 0; }
|