initial commit
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
BasedOnStyle: Google
|
||||
AllowShortFunctionsOnASingleLine: false
|
||||
SpaceAfterCStyleCast: true
|
||||
PointerBindsToType: false
|
||||
DerivePointerBinding: false
|
||||
IncludeBlocks: Preserve
|
||||
@@ -0,0 +1,5 @@
|
||||
build
|
||||
*.o
|
||||
sch
|
||||
schc
|
||||
.cache
|
||||
@@ -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}
|
||||
)
|
||||
@@ -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
|
||||
@@ -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)
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user