initial commit

This commit is contained in:
wt
2026-02-13 18:01:07 +07:00
commit 8e54631e4b
8 changed files with 303 additions and 0 deletions
+6
View File
@@ -0,0 +1,6 @@
BasedOnStyle: Google
AllowShortFunctionsOnASingleLine: false
SpaceAfterCStyleCast: true
PointerBindsToType: false
DerivePointerBinding: false
IncludeBlocks: Preserve
+5
View File
@@ -0,0 +1,5 @@
build
*.o
sch
schc
.cache
+17
View File
@@ -0,0 +1,17 @@
cmake_minimum_required (VERSION 3.6)
project(sch LANGUAGES C)
set(CMAKE_C_STANDARD 23)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
FILE(GLOB_RECURSE SOURCES src/main.c)
FILE(GLOB_RECURSE SOURCES_CLIENT src/client.c)
add_executable(
sch
${SOURCES}
)
add_executable(
schc
${SOURCES_CLIENT}
)
+29
View File
@@ -0,0 +1,29 @@
CC = gcc
CFLAGS = -Wall -g -std=gnu2x
LDFLAGS =
LIBS =
INCLUDES = -I./src/lib -I./src
SRCS = src/main.c
CSRCS = src/client.c
OBJS = src/main.o
COBJS = src/client.o
TARGET = sch
CTARGET = schc
CROSS_COMPILE =
all: $(TARGET) $(CTARGET)
$(TARGET): $(OBJS)
$(CROSS_COMPILE)$(CC) $(LDFLAGS) $^ -o $@ $(LIBS)
$(CTARGET): $(COBJS)
$(CROSS_COMPILE)$(CC) $(LDFLAGS) $^ -o $@ $(LIBS)
%.o: %.c
$(CROSS_COMPILE)$(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@
clean:
rm -f $(OBJS) $(TARGET) $(CTARGET)
test: $(TARGET)
bash ./tests.sh
+4
View File
@@ -0,0 +1,4 @@
project('sch', 'c', default_options: ['cpp_std=c20'])
include_dirs = include_directories('src')
executable('sch', 'src/main.c', include_directories: include_dirs, install: true)
executable('schc', 'src/client.c', include_directories: include_dirs, install: true)
+55
View File
@@ -0,0 +1,55 @@
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#define PORT 5555
#define BUFFER_SIZE 1024
int main() {
int sock;
struct sockaddr_in server_addr;
char buffer[BUFFER_SIZE];
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0) {
perror("socket");
return 1;
}
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(PORT);
inet_pton(AF_INET, "127.0.0.1", &server_addr.sin_addr);
if (connect(sock, (struct sockaddr *) &server_addr, sizeof(server_addr)) <
0) {
perror("connect");
return 1;
}
if (fork() == 0) {
// Процесс чтения
while (1) {
int valread = read(sock, buffer, BUFFER_SIZE);
if (valread > 0) {
buffer[valread] = '\0';
printf("%s", buffer);
}
}
} else {
char username[50];
fgets(username, 50, stdin);
username[strlen(username)-1] = '\0';
send(sock, username, 50, 0);
printf("username = %s\n", username);
// Процесс отправки
while (1) {
fgets(buffer, BUFFER_SIZE, stdin);
send(sock, buffer, strlen(buffer), 0);
}
}
return 0;
}
+61
View File
@@ -0,0 +1,61 @@
#ifndef COLORS_H
#define COLORS_H
#define RESET "\033[0m"
#define GREEN "\033[0;32m" // GREEN
#define BLUE "\033[0;34m" // BLUE
#define YELLOW "\033[1;33m" // YELLOW
#define RED "\033[0;31m" // RED
#define BLACK "\033[0;30m" // BLACK
#define PURPLE "\033[0;35m" // PURPLE
#define CYAN "\033[0;36m" // CYAN
#define WHITE "\033[0;37m" // WHITE
#define BBLACK "\033[1;30m" // BLACK
#define BRED "\033[1;31m" // RED
#define BGREEN "\033[1;32m" // GREEN
#define BYELLOW "\033[1;33m" // YELLOW
#define BBLUE "\033[1;34m" // BLUE
#define BPURPLE "\033[1;35m" // PURPLE
#define BCYAN "\033[1;36m" // CYAN
#define BWHITE "\033[1;37m" // WHITE
#define UBLACK "\033[4;30m" // BLACK
#define URED "\033[4;31m" // RED
#define UGREEN "\033[4;32m" // GREEN
#define UYELLOW "\033[4;33m" // YELLOW
#define UBLUE "\033[4;34m" // BLUE
#define UPURPLE "\033[4;35m" // PURPLE
#define UCYAN "\033[4;36m" // CYAN
#define UWHITE "\033[4;37m" // WHITE
#define ON_BLACK "\033[40m" // BLACK
#define ON_RED "\033[41m" // RED
#define ON_GREEN "\033[42m" // GREEN
#define ON_YELLOW "\033[43m" // YELLOW
#define ON_BLUE "\033[44m" // BLUE
#define ON_PURPLE "\033[45m" // PURPLE
#define ON_CYAN "\033[46m" // CYAN
#define ON_WHITE "\033[47m" // WHITE
#define IBLACK "\033[0;90m" // BLACK
#define IRED "\033[0;91m" // RED
#define IGREEN "\033[0;92m" // GREEN
#define IYELLOW "\033[0;93m" // YELLOW
#define IBLUE "\033[0;94m" // BLUE
#define IPURPLE "\033[0;95m" // PURPLE
#define ICYAN "\033[0;96m" // CYAN
#define IWHITE "\033[0;97m" // WHITE
#define BIBLACK "\033[1;90m" // BLACK
#define BIRED "\033[1;91m" // RED
#define BIGREEN "\033[1;92m" // GREEN
#define BIYELLOW "\033[1;93m" // YELLOW
#define BIBLUE "\033[1;94m" // BLUE
#define BIPURPLE "\033[1;95m" // PURPLE
#define BICYAN "\033[1;96m" // CYAN
#define BIWHITE "\033[1;97m" // WHITE
#define ON_IBLACK "\033[0;100m" // BLACK
#define ON_IRED "\033[0;101m" // RED
#define ON_IGREEN "\033[0;102m" // GREEN
#define ON_IYELLOW "\033[0;103m" // YELLOW
#define ON_IBLUE "\033[0;104m" // BLUE
#define ON_IPURPLE "\033[0;105m" // PURPLE
#define ON_ICYAN "\033[0;106m" // CYAN
#define ON_IWHITE "\033[0;107m" // WHITE
#endif
+126
View File
@@ -0,0 +1,126 @@
#include <arpa/inet.h>
#include <asm-generic/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <unistd.h>
#define PORT 5555
#define MAX_CLIENTS 10
#define BUFFER_SIZE 1024
struct client_t {
int sock;
char username[50];
};
int main() {
int server_fd;
struct client_t clients[MAX_CLIENTS];
struct sockaddr_in address;
int addrlen = sizeof(address);
fd_set readfds;
char buffer[BUFFER_SIZE];
for (int i = 0; i < MAX_CLIENTS; i++) {
clients[i].sock = 0;
bzero(clients[i].username, sizeof(clients[i].username));
}
server_fd = socket(AF_INET, SOCK_STREAM, 0);
if (server_fd < 0) {
perror("socket");
exit(EXIT_FAILURE);
}
int opt = 1;
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) {
perror("setsockopt");
exit(EXIT_FAILURE);
}
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(PORT);
if (bind(server_fd, (struct sockaddr *) &address, sizeof(address)) < 0) {
perror("bind");
exit(EXIT_FAILURE);
}
if (listen(server_fd, 5) < 0) {
perror("listen");
exit(EXIT_FAILURE);
}
printf("Chat server started on port %d\n", PORT);
while (1) {
FD_ZERO(&readfds);
FD_SET(server_fd, &readfds);
int max_sd = server_fd;
for (int i = 0; i < MAX_CLIENTS; i++) {
int sd = clients[i].sock;
if (sd > 0) FD_SET(sd, &readfds);
if (sd > max_sd) max_sd = sd;
}
if (select(max_sd + 1, &readfds, NULL, NULL, NULL) < 0) {
perror("select");
exit(EXIT_FAILURE);
}
// Новое подключение
if (FD_ISSET(server_fd, &readfds)) {
int new_socket = accept(server_fd, (struct sockaddr *) &address,
(socklen_t *) &addrlen);
printf("New connection: socket %d\n", new_socket);
read(new_socket, buffer, BUFFER_SIZE);
for (int i = 0; i < MAX_CLIENTS; i++) {
if (clients[i].sock == 0) {
clients[i].sock = new_socket;
strcpy(clients[i].username, buffer);
break;
}
}
}
// Сообщения от клиентов
for (int i = 0; i < MAX_CLIENTS; i++) {
int sd = clients[i].sock;
char sd_username[50];
bzero(sd_username, sizeof(sd_username));
strcpy(sd_username, clients[i].username);
if (FD_ISSET(sd, &readfds)) {
int valread = read(sd, buffer, BUFFER_SIZE);
if (valread == 0) {
printf("Client disconnected: socket %d\n", sd);
close(sd);
clients[i].sock = 0;
bzero(clients[i].username, sizeof(clients[i].username));
} else {
buffer[valread] = '\0';
printf("from_socket: %d\n", sd);
printf("from_username: %s\n", sd_username);
printf("Message: %s\n", buffer);
// Рассылка всем другим
for (int j = 0; j < MAX_CLIENTS; j++) {
if (clients[j].sock != 0 && clients[j].sock != sd) {
send(clients[j].sock, buffer, strlen(buffer), 0);
}
}
}
}
}
}
return 0;
}