// Client will be nc (netcat) // We only receive text that should be relayed to everybody else // The first thing the client says will be their name from then forward! #include #include #include #include #include #include #include #include #include #include using namespace std; #define BUFSIZE 1024 vector clients; void client_thread(int client_fd){ char buffer[BUFSIZE]; char name[BUFSIZE]; ssize_t readlen; size_t namelen; printf("Starting thread for client_fd %d\n", client_fd); readlen = read(client_fd, buffer, BUFSIZE - 2); buffer[readlen-1] = ':'; buffer[readlen] = ' '; buffer[readlen + 1] = 0; strcpy(name, buffer); namelen = strlen(name); printf("Client formerly known as fd %d is named %s\n", client_fd, name); clients.push_back(client_fd); while(true){ readlen = read(client_fd, buffer, BUFSIZE - 1); if(readlen < 1) break; buffer[readlen] = 0; printf(buffer); for(auto c : clients) if(c != client_fd){ write(c, name, strlen(name)); write(c, buffer, readlen); } } for(int i = 0; i < clients.size(); i++){ if(clients[i] == client_fd){ // Then it's our entry clients[i] = clients[clients.size() - 1]; clients.pop_back(); } } close(client_fd); } int main(int argc, char ** argv){ struct sockaddr_in sad; sad.sin_port = htons(5143); sad.sin_addr.s_addr = INADDR_ANY; sad.sin_family = AF_INET; int skt = socket(AF_INET, SOCK_STREAM, 0); // Step 1 if(skt == -1){ perror("socket"); return 1; } if( bind(skt, (struct sockaddr*)(&sad), sizeof(struct sockaddr_in)) ){ // step 2 perror("bind"); return 1; } if( listen(skt, 5) ){ // step 3 perror("listen"); return 1; } vector threads; while(1){ int client_fd; struct sockaddr_in client_address; socklen_t address_size = sizeof(struct sockaddr_in); client_fd = accept(skt, (struct sockaddr *)(&client_address), &address_size); // step 4 printf("Connection made from address %s\n", inet_ntoa(client_address.sin_addr)); threads.push_back(thread(client_thread, client_fd)); } return 0; }