#include #include #include #include #include #include #include #include #include #include #include using namespace std; struct client_parameters{ int fd; struct sockaddr_in address; }; vector client_fds; void* handle_client(void *param){ struct client_parameters *cp = (struct client_parameters*)param; client_fds.push_back(cp->fd); printf("Connection made from address %s\n", inet_ntoa(cp->address.sin_addr)); write(cp->fd, "Good Morning\n", 13); char client_message[100]; while(1){ memset(client_message, 0, 99); // Slower, but yields a clean slate, fixes null terminator problem ssize_t readlen = read(cp->fd, client_message, 100); // client_message[readlen] = 0; // Faster, since we place the null terminator right where it needs to be if(readlen <= 0) break; printf("Client %d sent: %s", cp->fd, client_message); // We need to relay this to other clients instead for(auto fd : client_fds){ if(fd != cp->fd) write(fd, client_message, readlen); } } printf("Client %d disconnected\n", cp->fd); // Remove from list of clients before we close for(int i = 0; i < client_fds.size(); i++){ if(client_fds[i] == cp->fd){ client_fds.erase(client_fds.begin() + i); // Could this cause a race condition? } } close(cp->fd); free(cp); return 0; } 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: Make a socket if(skt == -1){ perror("socket"); return 1; } if( bind(skt, (struct sockaddr*)(&sad), sizeof(struct sockaddr_in)) ){ // Step 2: Bind the socket to a port perror("bind"); return 1; } if( listen(skt, 5) ){ // step 3 perror("listen"); return 1; } 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 pthread_t thread_handle; struct client_parameters *cp = (struct client_parameters*)malloc(sizeof(struct client_parameters)); cp->fd = client_fd; cp->address = client_address; pthread_create(&thread_handle, 0, handle_client, cp); } return 0; }