commit 560be0ebd9fb363a866c9046cbab25ee19825e36 Author: TolaMironcenko Date: Tue Aug 2 06:25:00 2022 +0700 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..51da08c --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*client +*server +*DS_Store \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..8744b5c --- /dev/null +++ b/Makefile @@ -0,0 +1,13 @@ +build: + clang++ -o server server.cpp + clang++ -o client client.cpp -std=c++11 + +runserver: + ./server 127.0.0.1 8000 + +runclient: + ./client 127.0.0.1 8000 + +start: + clang++ -o main *.cpp + ./main \ No newline at end of file diff --git a/client.cpp b/client.cpp new file mode 100644 index 0000000..62bfc9e --- /dev/null +++ b/client.cpp @@ -0,0 +1,73 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + +void send_message(int sockfd, struct sockaddr_in addr) { + while (1) { + char buffer[1024]; + bzero(buffer, 1024); + cin.getline(buffer, 1024); + sendto(sockfd, buffer, 1024, 0, (struct sockaddr*)&addr, sizeof(addr)); + } +} + +int main(int argc, char** argv) { + + if (argc != 3) { + printf("Usage: %s ip port\n", argv[0]); + exit(0); + } + if (strlen(*argv) < 3) { + printf("Usage: %s ip port\n", argv[0]); + exit(0); + } + + char* ip = argv[1]; + int port = atoi(argv[2]); + + int sockfd; + struct sockaddr_in addr; + char buffer[1024]; + socklen_t addr_size; + + sockfd = socket(AF_INET, SOCK_DGRAM, 0); + if (sockfd < 0) { + perror("[-] socket error"); + exit(1); + } + + memset(&addr, '\0', sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons(port); + addr.sin_addr.s_addr = inet_addr(ip); + + char username[50]; + cout << "Enter tour username:" << endl; + bzero(username, 50); + cin.getline(username, 50); + sendto(sockfd, username, 50, 0, (struct sockaddr*)&addr, sizeof(addr)); + cout << "Your username: " << username << endl; + + thread t1(send_message, sockfd, addr); + + while (1) { + bzero(buffer, 1024); + addr_size = sizeof(addr); + recvfrom(sockfd, buffer, 1024, 0, (struct sockaddr*)&addr, &addr_size); + cout << buffer << endl; + } + + + t1.join(); + return 0; + +} \ No newline at end of file diff --git a/server.cpp b/server.cpp new file mode 100644 index 0000000..b00747b --- /dev/null +++ b/server.cpp @@ -0,0 +1,134 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + +//структура одного клиента на сервере +struct client_t { + sockaddr_in addr; + char username[1024]; //пример данных которые нужно менять при отправке пакета от клиента на наш сервер +}; + +const int num_of_clients = 64; // количество клиентов +client_t clients[num_of_clients]; + +bool HaveClient(sockaddr_in addr) +{ + for(int i = 0; i < num_of_clients; i++) + if(clients[i].addr.sin_addr.s_addr == addr.sin_addr.s_addr && clients[i].addr.sin_port == addr.sin_port) + return true; + + return false; +} + +int main(int argc, char** argv) { + + if (argc != 3) { + printf("Usage: %s ip port\n", argv[0]); + exit(0); + } + + char* ip = argv[1]; + int port = atoi(argv[2]); + + int sockfd = -1; + struct sockaddr_in server_addr; + socklen_t addr_size; + int n; + + sockfd = socket(AF_INET, SOCK_DGRAM, 0); + if (sockfd < 0) { + perror("[-] socket error"); + exit(1); + } + + memset(&server_addr, '\0', sizeof(server_addr)); + server_addr.sin_family = AF_INET; + server_addr.sin_port = htons(port); + server_addr.sin_addr.s_addr = inet_addr(ip); + + n = bind(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr)); + + if (n < 0) { + perror("[-] bind error"); + exit(1); + } + + sockaddr_in client_addr; + unsigned int clientlength = sizeof(client_addr); + + for (int i = 0; i < num_of_clients; i++) { + cout << clients[i].addr.sin_port << clients[i].addr.sin_addr.s_addr << ";"; + } + + + char buffer[1024]; + fd_set rset; + + FD_ZERO(&rset); + int maxfdp1 = sockfd + 1; + int nready; + + while (1) { + FD_SET(sockfd, &rset); + if ((select(maxfdp1, &rset, NULL, NULL, NULL)) < 0) { + if (errno == EINTR) + continue; + else + perror("select error"); + } + + if (FD_ISSET(sockfd, &rset)) { + bzero(buffer, 1024); + clientlength = sizeof(client_addr); + int bytesin = recvfrom(sockfd, buffer, 1024, 0, (sockaddr *) &client_addr, &clientlength); + if (bytesin < 0) { + cout << "error receving from client" << endl; + continue; + } + if (!HaveClient(client_addr)) { + for(int i = 0; i < num_of_clients; i++) { + if (clients[i].addr.sin_port == 0 && clients[i].addr.sin_addr.s_addr == 0) { + clients[i].addr = client_addr; + strcpy(clients[i].username, buffer); + break; + } + } + }else { + for (int i = 0; i < num_of_clients; i++) { + if (clients[i].addr.sin_port != 0 && clients[i].addr.sin_addr.s_addr != 0) { + if (!(clients[i].addr.sin_port == client_addr.sin_port && clients[i].addr.sin_addr.s_addr == client_addr.sin_addr.s_addr)) { + char res[1024]; + char time[128]; + std::time_t t = std::time(nullptr); + std::tm* now = std::localtime(&t); + strftime(time, sizeof(time), "%X", now); + + for (int i = 0; i < num_of_clients; i++) { + if (clients[i].addr.sin_addr.s_addr == client_addr.sin_addr.s_addr && clients[i].addr.sin_port == client_addr.sin_port) { + strcpy(res, clients[i].username); + } + } + strcat(res, " ["); + strcat(res, time); + strcat(res, "] : "); + strcat(res, buffer); + sendto(sockfd, res, 1024, 0, (sockaddr *) &clients[i].addr, sizeof(clients[i].addr)); + } + } + } + } + } + } + + return 0; +} \ No newline at end of file