Skip to content

Instantly share code, notes, and snippets.

@alirezaarzehgar
Last active October 19, 2022 06:57
Show Gist options
  • Select an option

  • Save alirezaarzehgar/1947b40be233f90b454d402954ebd41d to your computer and use it in GitHub Desktop.

Select an option

Save alirezaarzehgar/1947b40be233f90b454d402954ebd41d to your computer and use it in GitHub Desktop.
Dirty cli chatapp with C
#include <arpa/inet.h>
#include <err.h>
#include <math.h>
#include <netinet/in.h>
#include <pthread.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <sys/socket.h>
#include <unistd.h>
#define PORT 1234
void *reader(void *arg) {
int fd = *(int *)arg, lencache = 4;
char buf[BUFSIZ] = {0};
while (read(fd, buf, sizeof(buf)) > 0) {
putchar('\r');
for (int i = 0; i < lencache; i++)
putchar(' ');
printf("\r%s", buf);
printf("You: ");
fflush(stdout);
lencache = strlen(buf) > 4 ? strlen(buf) : 4;
bzero(buf, sizeof(buf));
}
return NULL;
}
int main(int argc, char **argv) {
int fd = 0;
char buf[BUFSIZ], msg[BUFSIZ];
struct sockaddr_in sa = {};
pthread_t thrd;
if (argc != 3) {
fprintf(stderr, "%s [IP] [NAME]\n", *argv);
return (EXIT_FAILURE);
}
if ((fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
err(EXIT_FAILURE, "socket()");
sa.sin_family = AF_INET;
sa.sin_port = htons(PORT);
if (!inet_pton(AF_INET, argv[1], &sa.sin_addr))
err(EXIT_FAILURE, "inet_pton()");
if (connect(fd, (const struct sockaddr *)&sa, sizeof(sa)))
err(EXIT_FAILURE, "connect()");
pthread_create(&thrd, NULL, reader, (void *)&fd);
printf("You: ");
while (fgets(msg, sizeof(msg), stdin)) {
sprintf(buf, "%s: %s", argv[2], msg);
write(fd, buf, strlen(buf));
printf("You: ");
bzero(buf, sizeof(buf));
bzero(msg, sizeof(msg));
}
close(fd);
return (EXIT_SUCCESS);
}
CC = cc
DEBUG = -g -fsanitize=address -fno-omit-frame-pointer
SRC = $(wildcard *.c)
TARGETS = $(SRC:.c=)
all: $(TARGETS)
%: %.c
$(CC) $(DEBUG) $< -o $@
clean:
rm -rf $(TARGETS)
#include <arpa/inet.h>
#include <err.h>
#include <netinet/in.h>
#include <pthread.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <sys/socket.h>
#include <unistd.h>
#define PORT 1234
#define LISTENQ 25
static int fds[LISTENQ] = {};
void *client_handler(void *arg) {
int index = 0, n = 0, fd = *((int *)arg);
char buf[BUFSIZ] = {0};
for (int i = 0; i < LISTENQ; i++)
if (fds[i] == fd) {
index = i;
break;
}
while ((n = read(fd, buf, sizeof(buf))) > 0) {
for (int i = 0; i < LISTENQ; i++)
if (fds[i] > 0 && fds[i] != fd) {
write(fds[i], buf, strlen(buf));
}
bzero(buf, sizeof(buf));
}
if (n < 0)
fprintf(stderr, "%d: read()", fd);
fds[index] = 0;
close(fd);
return NULL;
}
int main(int argc, char **argv) {
int fd = 0;
struct sockaddr_in sa = {};
pthread_t thrd;
if ((fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
err(EXIT_FAILURE, "socket()");
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &(int){1}, sizeof(int)) < 0)
err(EXIT_FAILURE, "setsockopt()");
sa.sin_family = AF_INET;
sa.sin_port = htons(PORT);
sa.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(fd, (const struct sockaddr *)&sa, sizeof(sa)))
err(EXIT_FAILURE, "bind()");
if (listen(fd, LISTENQ))
err(EXIT_FAILURE, "listen()");
while (true) {
int p = 0, index = 0;
for (int i = 0; i < LISTENQ; i++)
if (!fds[i]) {
index = i;
break;
}
if ((fds[index] = accept(fd, (struct sockaddr *)NULL, NULL)) < 0) {
perror("accept()");
continue;
}
pthread_create(&thrd, NULL, client_handler, (void *)&fds[index]);
}
return (EXIT_SUCCESS);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment