「✨」 feat: working bitch
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@ -1 +1,2 @@
|
||||
.direnv
|
||||
a.out
|
||||
|
95
mini_serv.c
95
mini_serv.c
@ -1,4 +1,5 @@
|
||||
#include <netinet/in.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -22,23 +23,102 @@ int sockfd;
|
||||
|
||||
fd_set main_fd, read_fd;
|
||||
|
||||
void send_all();
|
||||
|
||||
int extract_message(char **buf, char **msg) {
|
||||
char *newbuf;
|
||||
int i;
|
||||
|
||||
*msg = 0;
|
||||
if (*buf == 0)
|
||||
return (0);
|
||||
i = 0;
|
||||
while ((*buf)[i]) {
|
||||
if ((*buf)[i] == '\n') {
|
||||
newbuf = calloc(1, sizeof(*newbuf) * (strlen(*buf + i + 1) + 1));
|
||||
if (newbuf == 0)
|
||||
return (-1);
|
||||
strcpy(newbuf, *buf + i + 1);
|
||||
*msg = *buf;
|
||||
(*msg)[i + 1] = 0;
|
||||
*buf = newbuf;
|
||||
return (1);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
char *str_join(char *buf, char *add) {
|
||||
char *newbuf;
|
||||
int len;
|
||||
|
||||
if (buf == 0)
|
||||
len = 0;
|
||||
else
|
||||
len = strlen(buf);
|
||||
newbuf = malloc(sizeof(*newbuf) * (len + strlen(add) + 1));
|
||||
if (newbuf == 0)
|
||||
return (0);
|
||||
newbuf[0] = 0;
|
||||
if (buf != 0)
|
||||
strcat(newbuf, buf);
|
||||
free(buf);
|
||||
strcat(newbuf, add);
|
||||
return (newbuf);
|
||||
}
|
||||
|
||||
void append_client(int cli_fd) {
|
||||
lastid++;
|
||||
clients[cli_fd].id = lastid;
|
||||
clients[cli_fd].msg = NULL;
|
||||
FD_SET(cli_fd, &main_fd);
|
||||
bzero(send_buf, 3000);
|
||||
sprintf(send_buf, "server: client %d just arrived\n", lastid);
|
||||
send_all(cli_fd);
|
||||
}
|
||||
|
||||
void send_all() {
|
||||
void rm_client(int cli_fd) {
|
||||
FD_CLR(cli_fd, &read_fd);
|
||||
sprintf(send_buf, "server: client %d, just left\n", clients[cli_fd].id);
|
||||
send_all(cli_fd);
|
||||
clients[cli_fd].id = -1;
|
||||
if (clients[cli_fd].msg != NULL) {
|
||||
free(clients[cli_fd].msg);
|
||||
clients[cli_fd].msg = NULL;
|
||||
}
|
||||
FD_CLR(cli_fd, &main_fd);
|
||||
close(cli_fd);
|
||||
}
|
||||
|
||||
int read_client(int fd) {
|
||||
char tmp[3000];
|
||||
int bytes;
|
||||
if ((bytes = recv(fd, tmp, 3000, 0)) <= 0)
|
||||
return (rm_client(fd), 0);
|
||||
tmp[bytes] = 0;
|
||||
clients[fd].msg = str_join(clients[fd].msg, tmp);
|
||||
char *line = 0;
|
||||
while (extract_message(&clients[fd].msg, &line)) {
|
||||
bzero(send_buf, 3000);
|
||||
sprintf(send_buf, "client %d: %s", clients[fd].id, line);
|
||||
send_all(fd);
|
||||
free(line);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void send_all(int cli_fd) {
|
||||
size_t len = strlen(send_buf);
|
||||
printf("%s", send_buf);
|
||||
|
||||
for (int i = 0; i <= maxfd; i++)
|
||||
if (FD_ISSET(i, &read_fd))
|
||||
if (FD_ISSET(i, &main_fd) != 0 && i != cli_fd && i != sockfd)
|
||||
send(i, send_buf, len, 0);
|
||||
}
|
||||
|
||||
int send_error(void) {
|
||||
for (int i = 0; i < FD_SETSIZE; i++)
|
||||
for (int i = 0; i < maxfd; i++)
|
||||
if (FD_ISSET(i, &main_fd))
|
||||
close(i);
|
||||
close(sockfd);
|
||||
@ -66,7 +146,7 @@ int main(int ac, char **av) {
|
||||
if (bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) != 0)
|
||||
return (send_error());
|
||||
|
||||
if (listen(sockfd, 10) != 0)
|
||||
if (listen(sockfd, SOMAXCONN) != 0)
|
||||
return (send_error());
|
||||
|
||||
FD_ZERO(&main_fd);
|
||||
@ -91,11 +171,10 @@ int main(int ac, char **av) {
|
||||
if (cli_fd > maxfd)
|
||||
maxfd = cli_fd;
|
||||
append_client(cli_fd);
|
||||
bzero(send_buf, 3000);
|
||||
sprintf(send_buf, "server: client %d just arrived\n",
|
||||
lastid);
|
||||
send_all();
|
||||
break;
|
||||
} else {
|
||||
if (!read_client(i))
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user