Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2d0bd162d6 | ||
|
|
896f1bb951 | ||
|
|
b0fb83e030 | ||
|
|
651e8ec5aa | ||
|
|
725777d4fa |
No files matched your search
@@ -5,6 +5,9 @@ set(CMAKE_CXX_STANDARD 20)
|
|||||||
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++20 -Wall")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++20 -Wall")
|
||||||
|
|
||||||
|
add_compile_options(-fsanitize=address)
|
||||||
|
add_link_options(-fsanitize=address)
|
||||||
|
|
||||||
include_directories(
|
include_directories(
|
||||||
include
|
include
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentStyleType="text/css" height="429px" preserveAspectRatio="none" style="width:782px;height:429px;background:#FFFFFF;" version="1.1" viewBox="0 0 782 429" width="782px" zoomAndPan="magnify"><defs/><g><rect fill="none" height="206.9297" style="stroke:#000000;stroke-width:1.5;" width="766" x="10" y="169.8281"/><rect fill="none" height="75.3984" style="stroke:#000000;stroke-width:1.5;" width="664.5" x="20" y="294.3594"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="75" x2="75" y1="36.2969" y2="393.7578"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="626.5" x2="626.5" y1="36.2969" y2="393.7578"/><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="90" x="30" y="5"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="76" x="37" y="24.9951">MazeClient</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="90" x="30" y="392.7578"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="76" x="37" y="412.7529">MazeClient</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="95" x="579.5" y="5"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="81" x="586.5" y="24.9951">MazeServer</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="95" x="579.5" y="392.7578"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="81" x="586.5" y="412.7529">MazeServer</text><polygon fill="#181818" points="615,63.4297,625,67.4297,615,71.4297,619,67.4297" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="75" x2="621" y1="67.4297" y2="67.4297"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="271" x="82" y="62.3638">Установка соединения (TCP, порт 2000)</text><polygon fill="#181818" points="86,92.5625,76,96.5625,86,100.5625,82,96.5625" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="80" x2="626" y1="96.5625" y2="96.5625"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="199" x="92" y="91.4966">Подтверждение соединения</text><polygon fill="#181818" points="615,121.6953,625,125.6953,615,129.6953,619,125.6953" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="75" x2="621" y1="125.6953" y2="125.6953"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="336" x="82" y="120.6294">Отправка имени игрока (строка, размер до 1 Кб)</text><polygon fill="#181818" points="86,150.8281,76,154.8281,86,158.8281,82,154.8281" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="80" x2="626" y1="154.8281" y2="154.8281"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="159" x="92" y="149.7622">Подтверждение имени</text><path d="M10,169.8281 L87,169.8281 L87,176.9609 L77,186.9609 L10,186.9609 L10,169.8281 " fill="#EEEEEE" style="stroke:#000000;stroke-width:1.5;"/><rect fill="none" height="206.9297" style="stroke:#000000;stroke-width:1.5;" width="766" x="10" y="169.8281"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="32" x="25" y="182.895">loop</text><text fill="#000000" font-family="sans-serif" font-size="11" font-weight="bold" lengthAdjust="spacing" textLength="99" x="102" y="182.0386">[Игровой цикл]</text><polygon fill="#181818" points="615,204.0938,625,208.0938,615,212.0938,619,208.0938" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="75" x2="621" y1="208.0938" y2="208.0938"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="483" x="82" y="203.0278">Отправка команды (вперёд/направо/назад/налево) - (строка, до 1 Кб)</text><line style="stroke:#181818;stroke-width:1.0;" x1="627" x2="669" y1="237.2266" y2="237.2266"/><line style="stroke:#181818;stroke-width:1.0;" x1="669" x2="669" y1="237.2266" y2="250.2266"/><line style="stroke:#181818;stroke-width:1.0;" x1="628" x2="669" y1="250.2266" y2="250.2266"/><polygon fill="#181818" points="638,246.2266,628,250.2266,638,254.2266,634,250.2266" style="stroke:#181818;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLengthLine truncated
|
||||||
|
@startuml
|
||||||
|
MazeClient -> MazeServer: Установка соединения (TCP, порт 2000)
|
||||||
|
MazeServer -> MazeClient: Подтверждение соединения
|
||||||
|
MazeClient -> MazeServer: Отправка имени игрока (строка, размер до 1 Кб)
|
||||||
|
MazeServer -> MazeClient: Подтверждение имени
|
||||||
|
loop Игровой цикл
|
||||||
|
MazeClient -> MazeServer: Отправка команды (вперёд/направо/назад/налево) - (строка, до 1 Кб)
|
||||||
|
MazeServer -> MazeServer: Проверка команды
|
||||||
|
MazeServer -> MazeClient: Отправка ответа (успешно/там стена/ошибка) - (строка такого же размера)
|
||||||
|
alt Команда "сдаюсь" или конец игры
|
||||||
|
MazeClient -> MazeServer: Закрытие соединения
|
||||||
|
MazeServer -> MazeClient: Подтверждение закрытия
|
||||||
|
end
|
||||||
|
end
|
||||||
|
@enduml
|
||||||
|
|
||||||
|
PlantUML version 1.2022.7(Mon Aug 22 17:01:30 UTC 2022)
|
||||||
|
(GPL source distribution)
|
||||||
|
Java Runtime: OpenJDK Runtime Environment
|
||||||
|
JVM: OpenJDK 64-Bit Server VM
|
||||||
|
Default Encoding: UTF-8
|
||||||
|
Language: en
|
||||||
|
Country: null
|
||||||
|
--></g></svg>
|
||||||
|
After Width: | Height: | Size: 8.0 KiB |
@@ -3,14 +3,15 @@
|
|||||||
|
|
||||||
## Протокол пользовательского уровня
|
## Протокол пользовательского уровня
|
||||||
UML-диаграмма протокола пользовательского уровня представлена на рисунке ниже.
|
UML-диаграмма протокола пользовательского уровня представлена на рисунке ниже.
|
||||||

|
|
||||||
|

|
||||||
|
|
||||||
## Описание работы приложения
|
## Описание работы приложения
|
||||||
Сервер `maze-server` ожидает подключения клиентов по протоколу TCP на заданный порт (по умолчанию 1024). После установления соединения сервер запрашивает имя игрока, а затем начинает игру в лабиринте. Лабиринт генерируется случайным образом при старте каждой новой игровой сессии. Гарантируется наличие хотя бы одного пути из начальной точки `(0, 0)` в конечную точку `(2, 2)`. Добавление дополнительных стен происходит с соблюдением условия достижимости цели.
|
Сервер `MazeServer` ожидает подключения клиентов по протоколу TCP на заданный порт (по умолчанию 2000). После установления соединения сервер запрашивает имя игрока, а затем начинает игру в лабиринте. Лабиринт генерируется случайным образом при старте каждой новой игровой сессии. Гарантируется наличие хотя бы одного пути из начальной точки `(0, 0)` в конечную точку `(2, 2)`. Добавление дополнительных стен происходит с соблюдением условия достижимости цели.
|
||||||
|
|
||||||
Cхема и нумерация клеток лабиринта представлена на рисунке ниже.
|
Cхема и нумерация клеток лабиринта представлена на рисунке ниже.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
Клиент отправляет команды движения ("вперёд", "направо", "налево", "назад") или команду "сдаюсь" для завершения игры. Сервер обрабатывает команды, проверяет возможность хода, обновляет состояние лабиринта и отправляет клиенту текстовый ответ с результатом хода, количеством оставшихся ходов и текущей позицией (в формате координат). Игра завершается, если игрок достигает конечной точки (позиция 8), исчерпывает ходы или сдаётся.
|
Клиент отправляет команды движения ("вперёд", "направо", "налево", "назад") или команду "сдаюсь" для завершения игры. Сервер обрабатывает команды, проверяет возможность хода, обновляет состояние лабиринта и отправляет клиенту текстовый ответ с результатом хода, количеством оставшихся ходов и текущей позицией (в формате координат). Игра завершается, если игрок достигает конечной точки (позиция 8), исчерпывает ходы или сдаётся.
|
||||||
|
|
||||||
@@ -24,9 +25,9 @@ Cхема и нумерация клеток лабиринта представ
|
|||||||
- `-s` — включает сервисный режим (без ограничений по количеству шагов).
|
- `-s` — включает сервисный режим (без ограничений по количеству шагов).
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./maze-server -h localhost -p 1024 -n 10 -s
|
./maze-server -h localhost -p 2000 -n 10 -s
|
||||||
```
|
```
|
||||||
По умолчанию сокет сервера связывается с адресом `localhost:1024`, игрокам разрешено 10 шагов, сервисный режим выключен.
|
По умолчанию сокет сервера связывается с адресом `localhost:2000`, игрокам разрешено 10 шагов, сервисный режим выключен.
|
||||||
|
|
||||||
Завершение работы сервера — `Ctrl+C`.
|
Завершение работы сервера — `Ctrl+C`.
|
||||||
|
|
||||||
@@ -47,7 +48,7 @@ Cхема и нумерация клеток лабиринта представ
|
|||||||
|
|
||||||
- `-p` — задаёт номер порта сервера.
|
- `-p` — задаёт номер порта сервера.
|
||||||
```bash
|
```bash
|
||||||
./maze_client -h localhost -p 1024
|
./maze_client -h localhost -p 2000
|
||||||
```
|
```
|
||||||
По умолчанию клиент пытается подключиться к адресу `localhost:1024`.
|
По умолчанию клиент пытается подключиться к адресу `localhost:2000`.
|
||||||
|
|
||||||
@@ -13,6 +13,9 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
|
|
||||||
|
/*! Размер буфера для обмена данными между сервером и клиентом. */
|
||||||
|
const int BUFFER_SIZE = 1024;
|
||||||
|
|
||||||
/*! Класс клиента для взаимодействия с сервером игры в лабиринт. */
|
/*! Класс клиента для взаимодействия с сервером игры в лабиринт. */
|
||||||
class Client{
|
class Client{
|
||||||
private:
|
private:
|
||||||
|
|||||||
+12
-3
@@ -49,6 +49,10 @@ void Client::run(const std::string& h, const unsigned short p) {
|
|||||||
std::string player_name;
|
std::string player_name;
|
||||||
std::getline(std::cin, player_name);
|
std::getline(std::cin, player_name);
|
||||||
|
|
||||||
|
if (player_name.empty() || player_name.size() > BUFFER_SIZE) {
|
||||||
|
throw std::runtime_error("Incorrect name!");
|
||||||
|
}
|
||||||
|
|
||||||
if (!ping(serv_addr)) {
|
if (!ping(serv_addr)) {
|
||||||
throw std::runtime_error("Connection lost!");
|
throw std::runtime_error("Connection lost!");
|
||||||
}
|
}
|
||||||
@@ -61,25 +65,30 @@ void Client::game(){
|
|||||||
std::cout << "Игра началась!" << std::endl;
|
std::cout << "Игра началась!" << std::endl;
|
||||||
//print_instructions();
|
//print_instructions();
|
||||||
|
|
||||||
char buffer[1024] = {0};
|
char buffer[BUFFER_SIZE] = {0};
|
||||||
while (true) {
|
while (true) {
|
||||||
std::cout << "Введите команду: ";
|
std::cout << "Введите команду: ";
|
||||||
std::string command;
|
std::string command;
|
||||||
std::getline(std::cin, command);
|
std::getline(std::cin, command);
|
||||||
|
|
||||||
|
if (command.empty() || command.size() > BUFFER_SIZE) {
|
||||||
|
std::cout << "Некорректная команда" << std::endl;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Отправка команды на сервер
|
// Отправка команды на сервер
|
||||||
send(sock, command.c_str(), command.size(), 0);
|
send(sock, command.c_str(), command.size(), 0);
|
||||||
|
|
||||||
// Получение ответа от сервера
|
// Получение ответа от сервера
|
||||||
memset(buffer, 0, sizeof(buffer));
|
memset(buffer, 0, sizeof(buffer));
|
||||||
int bytes_received = recv(sock, buffer, sizeof(buffer), 0);
|
int bytes_received = recv(sock, buffer, sizeof(buffer), 0);
|
||||||
if (bytes_received <= 0) {
|
if (bytes_received == 0 || bytes_received > BUFFER_SIZE) {
|
||||||
throw std::runtime_error("Connection lost!");
|
throw std::runtime_error("Connection lost!");
|
||||||
//break;
|
//break;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string response(buffer);
|
std::string response(buffer);
|
||||||
std::cout << "Ответ сервера: " << response;
|
std::cout << "Ответ сервера: " << response << std::endl;
|
||||||
|
|
||||||
// Проверка завершения игры
|
// Проверка завершения игры
|
||||||
if (response.find("вы выиграли") != std::string::npos ||
|
if (response.find("вы выиграли") != std::string::npos ||
|
||||||
|
|||||||
@@ -28,7 +28,7 @@
|
|||||||
int main(int argc, char** argv){
|
int main(int argc, char** argv){
|
||||||
int opt;
|
int opt;
|
||||||
std::string host = "localhost";
|
std::string host = "localhost";
|
||||||
short unsigned port = 1024u;
|
short unsigned port = 2000u;
|
||||||
|
|
||||||
while ((opt = getopt(argc, argv, "h:p:")) != -1) {
|
while ((opt = getopt(argc, argv, "h:p:")) != -1) {
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
|
|||||||
@@ -6,6 +6,8 @@
|
|||||||
#include "maze.hpp"
|
#include "maze.hpp"
|
||||||
|
|
||||||
Maze::Maze(bool _test_mode, int _steps){
|
Maze::Maze(bool _test_mode, int _steps){
|
||||||
|
// Инициализация графа лабиринта и его ребер
|
||||||
|
// Индексы направлений: 0 - север, 1 - восток, 2 - юг, 3 - запад
|
||||||
std::vector<Edge> edges = {
|
std::vector<Edge> edges = {
|
||||||
{0, 1, 1, 3}, {0, 0, 3, 2}, {1, 1, 2, 3}, {1, 0, 4, 2},
|
{0, 1, 1, 3}, {0, 0, 3, 2}, {1, 1, 2, 3}, {1, 0, 4, 2},
|
||||||
{2, 0, 5, 2}, {3, 1, 4, 3}, {3, 0, 6, 2}, {4, 1, 5, 3},
|
{2, 0, 5, 2}, {3, 1, 4, 3}, {3, 0, 6, 2}, {4, 1, 5, 3},
|
||||||
@@ -18,11 +20,14 @@ Maze::Maze(bool _test_mode, int _steps){
|
|||||||
graph[i] = std::vector<bool>(DIRECTIONS, true);
|
graph[i] = std::vector<bool>(DIRECTIONS, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Выставление внешних стен
|
||||||
graph[6][0] = graph[7][0] = graph[8][0] = false;
|
graph[6][0] = graph[7][0] = graph[8][0] = false;
|
||||||
graph[0][2] = graph[1][2] = graph[2][2] = false;
|
graph[0][2] = graph[1][2] = graph[2][2] = false;
|
||||||
graph[0][3] = graph[3][3] = graph[6][3] = false;
|
graph[0][3] = graph[3][3] = graph[6][3] = false;
|
||||||
graph[2][1] = graph[5][1] = graph[8][1] = false;
|
graph[2][1] = graph[5][1] = graph[8][1] = false;
|
||||||
|
|
||||||
|
|
||||||
|
// Добавление внутренних стен
|
||||||
std::mt19937 rng(time(nullptr));
|
std::mt19937 rng(time(nullptr));
|
||||||
std::shuffle(edges.begin(), edges.end(), rng);
|
std::shuffle(edges.begin(), edges.end(), rng);
|
||||||
int walls_to_add = std::uniform_int_distribution<int>(MIN_WALLS, MAX_WALLS)(rng);
|
int walls_to_add = std::uniform_int_distribution<int>(MIN_WALLS, MAX_WALLS)(rng);
|
||||||
@@ -31,6 +36,7 @@ Maze::Maze(bool _test_mode, int _steps){
|
|||||||
const auto& edge = edges[i];
|
const auto& edge = edges[i];
|
||||||
graph[edge.node1][edge.dir1] = false;
|
graph[edge.node1][edge.dir1] = false;
|
||||||
graph[edge.node2][edge.dir2] = false;
|
graph[edge.node2][edge.dir2] = false;
|
||||||
|
// Проверка на существование пути
|
||||||
if (!is_path_exists(0, 8)) {
|
if (!is_path_exists(0, 8)) {
|
||||||
graph[edge.node1][edge.dir1] = true;
|
graph[edge.node1][edge.dir1] = true;
|
||||||
graph[edge.node2][edge.dir2] = true;
|
graph[edge.node2][edge.dir2] = true;
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ void Server::handle_client(int client_socket, bool mode, int steps) {
|
|||||||
std::string response;
|
std::string response;
|
||||||
|
|
||||||
int bytes_received = recv(client_socket, buffer, sizeof(buffer), 0);
|
int bytes_received = recv(client_socket, buffer, sizeof(buffer), 0);
|
||||||
if (bytes_received <= 0) {
|
if (bytes_received <= 0 || bytes_received > BUFFER_SIZE) {
|
||||||
std::cout << "Error in getting player name" << std::endl;;
|
std::cout << "Error in getting player name" << std::endl;;
|
||||||
close(client_socket);
|
close(client_socket);
|
||||||
return;
|
return;
|
||||||
@@ -55,7 +55,7 @@ void Server::handle_client(int client_socket, bool mode, int steps) {
|
|||||||
memset(buffer, 0, sizeof(buffer));
|
memset(buffer, 0, sizeof(buffer));
|
||||||
bytes_received = recv(client_socket, buffer, sizeof(buffer), 0);
|
bytes_received = recv(client_socket, buffer, sizeof(buffer), 0);
|
||||||
|
|
||||||
if (bytes_received <= 0) {
|
if (bytes_received <= 0 || bytes_received > BUFFER_SIZE) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,7 +65,7 @@ void Server::handle_client(int client_socket, bool mode, int steps) {
|
|||||||
int direction = -1;
|
int direction = -1;
|
||||||
int new_position = current_position;
|
int new_position = current_position;
|
||||||
|
|
||||||
if (command == "вперёд") {
|
if (command == "вперед") {
|
||||||
direction = 0;
|
direction = 0;
|
||||||
new_position = current_position + 3;
|
new_position = current_position + 3;
|
||||||
} else if (command == "направо") {
|
} else if (command == "направо") {
|
||||||
@@ -94,14 +94,14 @@ void Server::handle_client(int client_socket, bool mode, int steps) {
|
|||||||
maze.set_moves_left(moves_left - 1);
|
maze.set_moves_left(moves_left - 1);
|
||||||
if (!check_status(maze))
|
if (!check_status(maze))
|
||||||
break;
|
break;
|
||||||
response = "там стена, осталось " + std::to_string(maze.get_moves_left()) + " ходов\n";
|
response = "там стена, осталось " + std::to_string(maze.get_moves_left()) + " ходов";
|
||||||
send(client_socket, response.c_str(), response.size(), 0);
|
send(client_socket, response.c_str(), response.size(), 0);
|
||||||
continue;
|
continue;
|
||||||
} else if (maze.is_wall(current_position, direction)) {
|
} else if (maze.is_wall(current_position, direction)) {
|
||||||
maze.set_moves_left(moves_left - 1);
|
maze.set_moves_left(moves_left - 1);
|
||||||
if (!check_status(maze))
|
if (!check_status(maze))
|
||||||
break;
|
break;
|
||||||
response = "там стена, осталось " + std::to_string(maze.get_moves_left()) + " ходов\n";
|
response = "там стена, осталось " + std::to_string(maze.get_moves_left()) + " ходов";
|
||||||
send(client_socket, response.c_str(), response.size(), 0);
|
send(client_socket, response.c_str(), response.size(), 0);
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
@@ -119,7 +119,7 @@ void Server::handle_client(int client_socket, bool mode, int steps) {
|
|||||||
|
|
||||||
int x = current_position % 3;
|
int x = current_position % 3;
|
||||||
int y = current_position / 3;
|
int y = current_position / 3;
|
||||||
std::string text("(" + std::to_string(x) + ", " + std::to_string(y) + ")\n");
|
std::string text("(" + std::to_string(x) + ", " + std::to_string(y) + ")");
|
||||||
response = "успешно, осталось " + std::to_string(maze.get_moves_left()) + " ходов. Вы находитесь в " + text;
|
response = "успешно, осталось " + std::to_string(maze.get_moves_left()) + " ходов. Вы находитесь в " + text;
|
||||||
send(client_socket, response.c_str(), response.size(), 0);
|
send(client_socket, response.c_str(), response.size(), 0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ int main(int argc, char **argv) {
|
|||||||
std::string host = "localhost";
|
std::string host = "localhost";
|
||||||
int steps = 10;
|
int steps = 10;
|
||||||
bool service_mode = false;
|
bool service_mode = false;
|
||||||
short unsigned port = 1024u;
|
short unsigned port = 2000u;
|
||||||
|
|
||||||
while ((opt = getopt(argc, argv, "h:p:sn:")) != -1) {
|
while ((opt = getopt(argc, argv, "h:p:sn:")) != -1) {
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
|
|||||||
Reference in new issue
Block a user