diff --git a/a.out b/a.out index 9bc6653..55034c7 100755 Binary files a/a.out and b/a.out differ diff --git a/mini_serv_02.c b/mini_serv_02.c new file mode 100644 index 0000000..0e4d10e --- /dev/null +++ b/mini_serv_02.c @@ -0,0 +1,128 @@ +#include +#include +#include +#include +#include +#include + +#define BUFSIZE 160000 +#define MSGSIZE 1024 + +typedef struct s_client { + int id; + char msg[MSGSIZE]; +} t_client; + +void error(char *msg) { + write(1, msg, strlen(msg)); + exit(1); +} + +void broadcast(fd_set *set, int max_fd, char *msg, int server_fd, int current_fd) { + for(int i = 0; i < max_fd; ++i) { + if (i == server_fd) + continue; + if (i == current_fd) + continue; + if (FD_ISSET(i, set)) + send(i, msg, strlen(msg), 0); + } +} + +int main(int ac, char **av) { + int server_fd; + int client_fd; + int id; + int port; + int max_fd; + int ret; + struct sockaddr_in addr; + socklen_t addr_len; + fd_set fdset; + fd_set rdset; + t_client clients[FD_SETSIZE]; + t_client client; + char buf[BUFSIZE]; + char msg[BUFSIZE]; + + if (ac != 2) + error("Wrong number of arguments\n"); + if ( (port = atoi(av[1])) == -1) + error("Fatal error\n"); + addr_len = sizeof(addr); + + // socket create and verification + server_fd = socket(AF_INET, SOCK_STREAM, 0); + if (server_fd == -1) + error("Fatal error\n"); + + // assign IP, PORT + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = htonl(2130706433); //127.0.0.1 + addr.sin_port = htons(port); + + // Binding newly created socket to given IP and verification + if ((bind(server_fd, (const struct sockaddr *)&addr, addr_len)) == -1) + error("Fatal error\n"); + if (listen(server_fd, 10) == -1) + error("Fatal error\n"); + + FD_ZERO(&fdset); + FD_SET(server_fd, &fdset); + max_fd = server_fd; + id = 0; + bzero(&clients, sizeof(clients)); + + while(1) { + rdset = fdset; + + select(max_fd + 1, &rdset, NULL, NULL, NULL); + + if (FD_ISSET(server_fd, &rdset)) { + client_fd = accept(server_fd, (struct sockaddr *)&addr, &addr_len); + FD_SET(client_fd, &fdset); + if (client_fd > max_fd) + max_fd = client_fd; + client = clients[client_fd]; + client.id = id; + bzero(client.msg, MSGSIZE); + sprintf(msg, "server: client %d arrived\n", client.id); + broadcast(&fdset, max_fd, msg, server_fd, client_fd); + id++; + } + + client_fd = 0; + while(client_fd <= max_fd) { + ret = 1; + if (FD_ISSET(client_fd, &rdset)) { + + client = clients[client_fd]; + bzero(buf, BUFSIZE); + ret = recv(client_fd, buf, BUFSIZE, 0); + + if (ret == 0) { + sprintf(msg, "server: client %d left\n", client.id); + broadcast(&fdset, max_fd, msg, server_fd, client_fd); + FD_CLR(client_fd, &fdset); + } + + else if (ret > 0) { + for(int i = 0, j = strlen(client.msg); i < ret; ++i, ++j) { + client.msg[j] = buf[i]; + if (buf[i] == '\n') { + client.msg[j] = '\0'; + sprintf(msg, "client %d: %s\n", client.id, client.msg); + broadcast(&fdset, max_fd, msg, server_fd, client_fd); + bzero(client.msg, MSGSIZE); + j = -1; + } + } + } + } + client_fd++; + } + } + return (0); +} + +