Created
February 6, 2025 07:55
-
-
Save sunmeat/830e8cb963ff95c76498c67e3714b300 to your computer and use it in GitHub Desktop.
server side macos
This file contains 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 <iostream> | |
#include <cstring> | |
#include <unistd.h> | |
#include <arpa/inet.h> | |
#include <netinet/in.h> | |
#include <sys/socket.h> | |
#include <sys/types.h> | |
using namespace std; | |
#define DEFAULT_BUFLEN 512 | |
#define DEFAULT_PORT 27015 | |
#define PAUSE 1000 | |
int main() | |
{ | |
setlocale(0, "Ukrainian"); | |
system("title SERVER SIDE"); | |
cout << "процес сервера запущено!\n"; | |
sleep(PAUSE); | |
////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
// створення сокета для сервера | |
int ListenSocket = socket(AF_INET, SOCK_STREAM, 0); | |
if (ListenSocket == -1) { | |
cout << "socket не вдалося створити з помилкою!\n"; | |
return 1; | |
} else { | |
cout << "створення сокета на серверi пройшло успiшно!\n"; | |
sleep(PAUSE); | |
} | |
////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
struct sockaddr_in serverAddr; | |
memset(&serverAddr, 0, sizeof(serverAddr)); | |
serverAddr.sin_family = AF_INET; | |
serverAddr.sin_addr.s_addr = INADDR_ANY; | |
serverAddr.sin_port = htons(DEFAULT_PORT); | |
// прив'язка сокета до порту | |
int bindResult = bind(ListenSocket, (struct sockaddr*)&serverAddr, sizeof(serverAddr)); | |
if (bindResult == -1) { | |
cout << "bind не вдалося з помилкою!\n"; | |
close(ListenSocket); | |
return 2; | |
} else { | |
cout << "впровадження сокету по IP-адресi пройшло успiшно!\n"; | |
sleep(PAUSE); | |
} | |
////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
// налаштування сокета для прослуховування | |
int listenResult = listen(ListenSocket, 10); | |
if (listenResult == -1) { | |
cout << "listen не вдалося з помилкою!\n"; | |
close(ListenSocket); | |
return 3; | |
} else { | |
cout << "починається прослуховування iнформацiї вiд клiєнта. будь ласка, запустiть клiєнтську програму!\n"; | |
} | |
////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
// прийом сокета клієнта | |
struct sockaddr_in clientAddr; | |
socklen_t clientAddrSize = sizeof(clientAddr); | |
int ClientSocket = accept(ListenSocket, (struct sockaddr*)&clientAddr, &clientAddrSize); | |
if (ClientSocket == -1) { | |
cout << "accept не вдалося з помилкою!\n"; | |
close(ListenSocket); | |
return 4; | |
} else { | |
cout << "пiдключення з клiєнтською програмою встановлено успiшно!\n"; | |
} | |
////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
// більше не потрібно зберігати сокет сервера | |
close(ListenSocket); | |
// отримання даних до того моменту, поки з'єднання не буде завершено | |
do { | |
char message[DEFAULT_BUFLEN]; | |
int iResult = recv(ClientSocket, message, DEFAULT_BUFLEN, 0); // функція recv використовується для читання вхідних даних | |
message[iResult] = '\0'; | |
if (iResult > 0) { | |
cout << "процес клiєнта надiслав повiдомлення: " << message << "\n"; | |
sleep(PAUSE); | |
cout << "байтiв отримано: " << iResult << "\n"; | |
sleep(PAUSE); | |
////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
// відправка відповіді назад відправнику | |
const char* answer = "and hello from server!"; | |
cout << "процес сервера вiдправляє вiдповiдь: " << answer << "\n"; | |
int iSendResult = send(ClientSocket, answer, strlen(answer), 0); // функція send відправляє дані на підключений сокет | |
sleep(PAUSE); | |
////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
if (iSendResult == -1) { | |
cout << "send не вдалося з помилкою!\n"; | |
close(ClientSocket); | |
return 5; | |
} else { | |
cout << "байтiв вiдправлено: " << iSendResult << "\n"; | |
sleep(PAUSE); | |
} | |
} | |
else if (iResult == 0) { | |
cout << "з'єднання закривається...\n"; | |
sleep(PAUSE); | |
} | |
else { | |
cout << "recv не вдалося з помилкою!\n"; | |
close(ClientSocket); | |
return 6; | |
} | |
} while (true); | |
////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
// закриття з'єднання, оскільки роботу завершено | |
int shutdownResult = shutdown(ClientSocket, SHUT_WR); // функція shutdown вимикає надсилання або отримання даних на сокеті | |
if (shutdownResult == -1) { | |
cout << "shutdown не вдалося з помилкою!\n"; | |
close(ClientSocket); | |
return 7; | |
} else { | |
cout << "процес сервера припиняє свою роботу! до нових запускiв! :)\n"; | |
} | |
// вивільнення памяті | |
close(ClientSocket); | |
return 0; | |
} | |
/* | |
1) Бібліотека winsock2.h була замінена на POSIX бібліотеки: | |
- #include <unistd.h> для sleep(). | |
- #include <arpa/inet.h> і #include <netinet/in.h> для роботи з мережевими адресами. | |
- #include <sys/socket.h> для роботи з сокетами. | |
2) Використання функцій, сумісних з POSIX: | |
- Для створення сокетів, прив'язки, прослуховування та прийому підключень. | |
- Замінено функції WSAStartup, WSACleanup, recv, send, і т.д., на їх аналоги в POSIX. | |
3) Заміна Sleep(PAUSE) на sleep(PAUSE). | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment