Last active
October 19, 2022 06:57
-
-
Save alirezaarzehgar/1947b40be233f90b454d402954ebd41d to your computer and use it in GitHub Desktop.
Dirty cli chatapp with C
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #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); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #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