diff --git a/lab0/hello/empty b/lab0/hello/empty new file mode 100644 index 000000000..e69de29bb diff --git a/lab0/hello/newhello.c b/lab0/hello/newhello.c new file mode 100755 index 000000000..c71ae2565 --- /dev/null +++ b/lab0/hello/newhello.c @@ -0,0 +1,6 @@ +#include + +int main() +{ + printf("Hello World!\n"); +} \ No newline at end of file diff --git a/lab1/proga b/lab1/proga new file mode 100755 index 000000000..5f263978b --- /dev/null +++ b/lab1/proga @@ -0,0 +1,7 @@ +#!/bin/bash + +echo "Текущий путь: $(pwd)" + +echo "Текущая дата и время: $(date)" + +echo $PATH \ No newline at end of file diff --git a/lab3/src/find_min_max.c b/lab3/src/find_min_max.c index 6662a8fba..0b1659d8a 100755 --- a/lab3/src/find_min_max.c +++ b/lab3/src/find_min_max.c @@ -1,3 +1,5 @@ +#include +#include #include "find_min_max.h" #include @@ -7,6 +9,16 @@ struct MinMax GetMinMax(int *array, unsigned int begin, unsigned int end) { min_max.min = INT_MAX; min_max.max = INT_MIN; - // your code here + for(int i = begin; i < end; i++){ + if (array[i] < min_max.min){ + min_max.min = array[i]; + } + + if (array[i] > min_max.max){ + min_max.max = array[i]; + } + } + return min_max; } + diff --git a/lab3/src/find_min_max.o b/lab3/src/find_min_max.o new file mode 100644 index 000000000..a451b3a35 Binary files /dev/null and b/lab3/src/find_min_max.o differ diff --git a/lab3/src/image-1.png b/lab3/src/image-1.png new file mode 100644 index 000000000..3dfa41eb2 Binary files /dev/null and b/lab3/src/image-1.png differ diff --git a/lab3/src/image-2.png b/lab3/src/image-2.png new file mode 100644 index 000000000..18274aa4e Binary files /dev/null and b/lab3/src/image-2.png differ diff --git a/lab3/src/image-3.png b/lab3/src/image-3.png new file mode 100644 index 000000000..654495ece Binary files /dev/null and b/lab3/src/image-3.png differ diff --git a/lab3/src/image-4.png b/lab3/src/image-4.png new file mode 100644 index 000000000..9a35b07c7 Binary files /dev/null and b/lab3/src/image-4.png differ diff --git a/lab3/src/image-5.png b/lab3/src/image-5.png new file mode 100644 index 000000000..04e4c89a3 Binary files /dev/null and b/lab3/src/image-5.png differ diff --git a/lab3/src/image-6.png b/lab3/src/image-6.png new file mode 100644 index 000000000..bf5b6adcf Binary files /dev/null and b/lab3/src/image-6.png differ diff --git a/lab3/src/image-7.png b/lab3/src/image-7.png new file mode 100644 index 000000000..bc0b9259d Binary files /dev/null and b/lab3/src/image-7.png differ diff --git a/lab3/src/image.png b/lab3/src/image.png new file mode 100644 index 000000000..c82a92917 Binary files /dev/null and b/lab3/src/image.png differ diff --git a/lab3/src/makefile b/lab3/src/makefile index 1538d9699..d2746dcbb 100755 --- a/lab3/src/makefile +++ b/lab3/src/makefile @@ -1,6 +1,10 @@ CC=gcc CFLAGS=-I. +.PHONY: all clean + +all: sequential_min_max parallel_min_max + sequential_min_max : utils.o find_min_max.o utils.h find_min_max.h $(CC) -o sequential_min_max find_min_max.o utils.o sequential_min_max.c $(CFLAGS) @@ -13,5 +17,8 @@ utils.o : utils.h find_min_max.o : utils.h find_min_max.h $(CC) -o find_min_max.o -c find_min_max.c $(CFLAGS) +run: run.c + $(CC) -o run run.c $(CFLAGS) + clean : - rm utils.o find_min_max.o sequential_min_max parallel_min_max + rm -f utils.o find_min_max.o sequential_min_max parallel_min_max diff --git a/lab3/src/min_max b/lab3/src/min_max new file mode 100755 index 000000000..6d87ea848 Binary files /dev/null and b/lab3/src/min_max differ diff --git a/lab3/src/parallel_min_max b/lab3/src/parallel_min_max new file mode 100755 index 000000000..544eb3742 Binary files /dev/null and b/lab3/src/parallel_min_max differ diff --git a/lab3/src/parallel_min_max.c b/lab3/src/parallel_min_max.c index acb35ec64..817ff799b 100755 --- a/lab3/src/parallel_min_max.c +++ b/lab3/src/parallel_min_max.c @@ -1,9 +1,11 @@ #include #include +#include #include #include #include #include +#include #include #include @@ -15,19 +17,30 @@ #include "find_min_max.h" #include "utils.h" +pid_t* pids; +int pnum = -1; + +void KILL_CHILDREN() { + printf("timeout exceeded. Killing children and exiting immediately\n"); + for (int i = 0; i < pnum; i++) { + kill(pids[i], 0); + } + + exit(0); +} + int main(int argc, char **argv) { int seed = -1; int array_size = -1; - int pnum = -1; bool with_files = false; + int timeout = -1; while (true) { - int current_optind = optind ? optind : 1; - static struct option options[] = {{"seed", required_argument, 0, 0}, {"array_size", required_argument, 0, 0}, {"pnum", required_argument, 0, 0}, {"by_files", no_argument, 0, 'f'}, + {"timeout", required_argument, 0, 0}, {0, 0, 0, 0}}; int option_index = 0; @@ -40,22 +53,35 @@ int main(int argc, char **argv) { switch (option_index) { case 0: seed = atoi(optarg); - // your code here - // error handling + if (seed <= 0) { + printf("seed must be a positive number\n"); + return 1; + } break; case 1: array_size = atoi(optarg); - // your code here - // error handling + if (array_size <= 0) { + printf("array size must be a positive number\n"); + return 1; + } break; case 2: pnum = atoi(optarg); - // your code here - // error handling + if (pnum <= 0) { + printf("pnum must be a positive number\n"); + return 1; + } break; case 3: with_files = true; break; + case 4: + timeout = atoi(optarg); + if (timeout <= 0) { + printf("timeout must be a positive number\n"); + return 1; + } + break; defalut: printf("Index %d is out of options\n", option_index); @@ -91,20 +117,53 @@ int main(int argc, char **argv) { struct timeval start_time; gettimeofday(&start_time, NULL); + pids = malloc(pnum * sizeof(pid_t)); + int* pipes = malloc(pnum * 2 * sizeof(int)); + + int baseChunkSize = array_size / pnum; + int extendedCount = array_size % pnum; + int j = 0; + + if (timeout > 0) { + signal(SIGALRM, KILL_CHILDREN); + alarm(timeout); + printf("Starting calculation with timeout %ds\n", timeout); + } + for (int i = 0; i < pnum; i++) { + int* readDescriptor = pipes + i * 2; + pipe(readDescriptor); + + int startIndex = j; + int endIndex = startIndex + baseChunkSize; + if (i < extendedCount) endIndex++; + j = endIndex; + pid_t child_pid = fork(); + if (child_pid >= 0) { - // successful fork - active_child_processes += 1; + pids[i] = child_pid; + active_child_processes++; if (child_pid == 0) { - // child process - - // parallel somehow + struct MinMax chunkResult = GetMinMax(array, startIndex, endIndex); if (with_files) { - // use files here + char fileName[40]; + sprintf(fileName, "./%d.txt", getpid()); + FILE* temporaryResultsFile = fopen(fileName, "w"); + if (!temporaryResultsFile) { + printf("Cannot open file %s\n", fileName); + return 1; + } + + fprintf(temporaryResultsFile, "%d %d", chunkResult.min, chunkResult.max); + fclose(temporaryResultsFile); } else { - // use pipe here + int* writeDescriptor = readDescriptor + 1; + write(*writeDescriptor, &chunkResult, sizeof(struct MinMax)); + + close(*readDescriptor); + close(*writeDescriptor); } return 0; } @@ -116,9 +175,14 @@ int main(int argc, char **argv) { } while (active_child_processes > 0) { - // your code here + int pid = pids[active_child_processes - 1]; + int code = waitpid(pid, NULL, 0); + if (!code) { + printf("Failed to wait for process with id: %d", pid); + return 1; + } - active_child_processes -= 1; + active_child_processes--; } struct MinMax min_max; @@ -130,9 +194,19 @@ int main(int argc, char **argv) { int max = INT_MIN; if (with_files) { - // read from files + char fileName[40]; + sprintf(fileName, "./%d.txt", pids[i]); + FILE* temporaryResultsFile = fopen(fileName, "r"); + + fscanf(temporaryResultsFile, "%d %d", &min, &max); + fclose(temporaryResultsFile); + remove(fileName); } else { - // read from pipes + int readDescriptor = pipes[i * 2]; + struct MinMax buff; + read(readDescriptor, &buff, sizeof(struct MinMax)); + min = buff.min; + max = buff.max; } if (min < min_max.min) min_max.min = min; @@ -146,10 +220,12 @@ int main(int argc, char **argv) { elapsed_time += (finish_time.tv_usec - start_time.tv_usec) / 1000.0; free(array); + free(pids); + free(pipes); printf("Min: %d\n", min_max.min); printf("Max: %d\n", min_max.max); printf("Elapsed time: %fms\n", elapsed_time); fflush(NULL); return 0; -} +} \ No newline at end of file diff --git a/lab3/src/readme.md b/lab3/src/readme.md new file mode 100644 index 000000000..77525f087 --- /dev/null +++ b/lab3/src/readme.md @@ -0,0 +1,46 @@ +# Задание 1 + +--- +![alt text](image.png) +--- + +```bash +@StarAres1 ➜ /workspaces/os_lab_2019 (master) $ gcc --version + +@StarAres1 ➜ /workspaces/os_lab_2019 (master) $ cd lab3 +@StarAres1 ➜ /workspaces/os_lab_2019/lab3 (master) $ cd src + +@StarAres1 ➜ /workspaces/os_lab_2019/lab3/src (master) $ gcc -c find_min_max.c +@StarAres1 ➜ /workspaces/os_lab_2019/lab3/src (master) $ gcc -c utils.c +@StarAres1 ➜ /workspaces/os_lab_2019/lab3/src (master) $ gcc -c sequantial_min_max.c + +@StarAres1 ➜ /workspaces/os_lab_2019/lab3/src (master) $ gcc find_min_max.o utils.c sequential_min_max.o -o min_max +@StarAres1 ➜ /workspaces/os_lab_2019/lab3/src (master) $ ./min_max 1 3 +``` +![alt text](image-1.png) +# Задание 2-3 + +--- +![alt text](image-2.png) +--- + +```bash +@StarAres1 ➜ /workspaces/os_lab_2019/lab3/src (master) $ gcc -o parallel_min_max parallel_min_max.c find_min_max.c utils.c -lm +``` +![alt text](image-3.png) + +# Задание 4 + +--- +![alt text](image-5.png) +--- + +![alt text](image-4.png) + +# Задание 5 + +--- +![alt text](image-6.png) +--- + +![alt text](image-7.png) \ No newline at end of file diff --git a/lab3/src/run b/lab3/src/run new file mode 100755 index 000000000..7d31fb16a Binary files /dev/null and b/lab3/src/run differ diff --git a/lab3/src/run.c b/lab3/src/run.c new file mode 100644 index 000000000..66b862098 --- /dev/null +++ b/lab3/src/run.c @@ -0,0 +1,34 @@ +#include +#include +#include +#include // Добавлено для waitpid + +int main(int argc, char *argv[]) { + // Проверка на наличие достаточного количества аргументов + if (argc != 3) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return 1; + } + + // Запуск приложения sequential_min_max + pid_t pid = fork(); + if (pid < 0) { + perror("Fork failed"); + return 1; // Ошибка при создании процесса + } else if (pid == 0) { + // Дочерний процесс + execl("./sequential_min_max", "sequential_min_max", argv[1], argv[2], (char *)NULL); + perror("execl failed"); // Если execl вернется, произошла ошибка + return 1; // Ошибка при выполнении execl + } else { + // Родительский процесс + int status; + waitpid(pid, &status, 0); // Ожидание завершения дочернего процесса + if (WIFEXITED(status)) { + printf("sequential_min_max exited with status %d\n", WEXITSTATUS(status)); + } else { + printf("sequential_min_max did not terminate normally\n"); + } + } + return 0; // Успешное завершение программы +} \ No newline at end of file diff --git a/lab3/src/sequential_min_max b/lab3/src/sequential_min_max new file mode 100755 index 000000000..6d87ea848 Binary files /dev/null and b/lab3/src/sequential_min_max differ diff --git a/lab3/src/sequential_min_max.c b/lab3/src/sequential_min_max.c index e6bd2d866..30944a75c 100755 --- a/lab3/src/sequential_min_max.c +++ b/lab3/src/sequential_min_max.c @@ -25,6 +25,11 @@ int main(int argc, char **argv) { int *array = malloc(array_size * sizeof(int)); GenerateArray(array, array_size, seed); struct MinMax min_max = GetMinMax(array, 0, array_size); + + for (int i = 0; i < array_size; i++){ + printf("%d ", array[i]); + } + free(array); printf("min: %d\n", min_max.min); diff --git a/lab3/src/sequential_min_max.o b/lab3/src/sequential_min_max.o new file mode 100644 index 000000000..4e07a8c17 Binary files /dev/null and b/lab3/src/sequential_min_max.o differ diff --git a/lab3/src/utils.o b/lab3/src/utils.o new file mode 100644 index 000000000..53c641244 Binary files /dev/null and b/lab3/src/utils.o differ diff --git a/lab4/src/find_min_max.c b/lab4/src/find_min_max.c new file mode 100644 index 000000000..d4a8a6d50 --- /dev/null +++ b/lab4/src/find_min_max.c @@ -0,0 +1,24 @@ +#include "find_min_max.h" + +#include + +struct MinMax GetMinMax(int *array, unsigned int begin, unsigned int end) { + struct MinMax min_max; + min_max.min = INT_MAX; + min_max.max = INT_MIN; + + for (int i = begin; imin_max.max){ + min_max.max = array[i]; + } + if (array[i] +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include "find_min_max.h" +#include "utils.h" + +pid_t* pids; +int pnum = -1; + +void KILL_CHILDREN() { + printf("timeout exceeded. Killing children and exiting immediately\n"); + for (int i = 0; i < pnum; i++) { + kill(pids[i], 0); + } + + exit(0); +} + +int main(int argc, char **argv) { + int seed = -1; + int array_size = -1; + bool with_files = false; + int timeout = -1; + + while (true) { + static struct option options[] = {{"seed", required_argument, 0, 0}, + {"array_size", required_argument, 0, 0}, + {"pnum", required_argument, 0, 0}, + {"by_files", no_argument, 0, 'f'}, + {"timeout", required_argument, 0, 0}, + {0, 0, 0, 0}}; + + int option_index = 0; + int c = getopt_long(argc, argv, "f", options, &option_index); + + if (c == -1) break; + + switch (c) { + case 0: + switch (option_index) { + case 0: + seed = atoi(optarg); + if (seed <= 0) { + printf("seed must be a positive number\n"); + return 1; + } + break; + case 1: + array_size = atoi(optarg); + if (array_size <= 0) { + printf("array size must be a positive number\n"); + return 1; + } + break; + case 2: + pnum = atoi(optarg); + if (pnum <= 0) { + printf("pnum must be a positive number\n"); + return 1; + } + break; + case 3: + with_files = true; + break; + case 4: + timeout = atoi(optarg); + if (timeout <= 0) { + printf("timeout must be a positive number\n"); + return 1; + } + break; + + defalut: + printf("Index %d is out of options\n", option_index); + } + break; + case 'f': + with_files = true; + break; + + case '?': + break; + + default: + printf("getopt returned character code 0%o?\n", c); + } + } + + if (optind < argc) { + printf("Has at least one no option argument\n"); + return 1; + } + + if (seed == -1 || array_size == -1 || pnum == -1) { + printf("Usage: %s --seed \"num\" --array_size \"num\" --pnum \"num\" \n", + argv[0]); + return 1; + } + + int *array = malloc(sizeof(int) * array_size); + GenerateArray(array, array_size, seed); + int active_child_processes = 0; + + struct timeval start_time; + gettimeofday(&start_time, NULL); + + pids = malloc(pnum * sizeof(pid_t)); + int* pipes = malloc(pnum * 2 * sizeof(int)); + + int baseChunkSize = array_size / pnum; + int extendedCount = array_size % pnum; + int j = 0; + + if (timeout > 0) { + signal(SIGALRM, KILL_CHILDREN); + alarm(timeout); + printf("Starting calculation with timeout %ds\n", timeout); + } + + for (int i = 0; i < pnum; i++) { + int* readDescriptor = pipes + i * 2; + pipe(readDescriptor); + + int startIndex = j; + int endIndex = startIndex + baseChunkSize; + if (i < extendedCount) endIndex++; + j = endIndex; + + pid_t child_pid = fork(); + + if (child_pid >= 0) { + // successful fork + pids[i] = child_pid; + active_child_processes++; + if (child_pid == 0) { + struct MinMax chunkResult = GetMinMax(array, startIndex, endIndex); + + if (with_files) { + char fileName[40]; + sprintf(fileName, "./%d.txt", getpid()); + FILE* temporaryResultsFile = fopen(fileName, "w"); + if (!temporaryResultsFile) { + printf("Cannot open file %s\n", fileName); + return 1; + } + + fprintf(temporaryResultsFile, "%d %d", chunkResult.min, chunkResult.max); + fclose(temporaryResultsFile); + } else { + int* writeDescriptor = readDescriptor + 1; + write(*writeDescriptor, &chunkResult, sizeof(struct MinMax)); + + close(*readDescriptor); + close(*writeDescriptor); + } + return 0; + } + + } else { + printf("Fork failed!\n"); + return 1; + } + } + + while (active_child_processes > 0) { + int pid = pids[active_child_processes - 1]; + int code = waitpid(pid, NULL, 0); + if (!code) { + printf("Failed to wait for process with id: %d", pid); + return 1; + } + + active_child_processes--; + } + + struct MinMax min_max; + min_max.min = INT_MAX; + min_max.max = INT_MIN; + + for (int i = 0; i < pnum; i++) { + int min = INT_MAX; + int max = INT_MIN; + + if (with_files) { + char fileName[40]; + sprintf(fileName, "./%d.txt", pids[i]); + FILE* temporaryResultsFile = fopen(fileName, "r"); + + fscanf(temporaryResultsFile, "%d %d", &min, &max); + fclose(temporaryResultsFile); + remove(fileName); + } else { + int readDescriptor = pipes[i * 2]; + struct MinMax buff; + read(readDescriptor, &buff, sizeof(struct MinMax)); + min = buff.min; + max = buff.max; + } + + if (min < min_max.min) min_max.min = min; + if (max > min_max.max) min_max.max = max; + } + + struct timeval finish_time; + gettimeofday(&finish_time, NULL); + + double elapsed_time = (finish_time.tv_sec - start_time.tv_sec) * 1000.0; + elapsed_time += (finish_time.tv_usec - start_time.tv_usec) / 1000.0; + + free(array); + free(pids); + free(pipes); + + printf("Min: %d\n", min_max.min); + printf("Max: %d\n", min_max.max); + printf("Elapsed time: %fms\n", elapsed_time); + fflush(NULL); + return 0; +} \ No newline at end of file diff --git a/lab4/src/parallel_sum b/lab4/src/parallel_sum new file mode 100644 index 000000000..5c37c369e Binary files /dev/null and b/lab4/src/parallel_sum differ diff --git a/lab4/src/parallel_sum.c b/lab4/src/parallel_sum.c old mode 100755 new mode 100644 index 66034d2c5..c30af4731 --- a/lab4/src/parallel_sum.c +++ b/lab4/src/parallel_sum.c @@ -1,63 +1,129 @@ -#include -#include -#include - -#include - -struct SumArgs { - int *array; - int begin; - int end; -}; - -int Sum(const struct SumArgs *args) { - int sum = 0; - // TODO: your code here - return sum; -} - -void *ThreadSum(void *args) { - struct SumArgs *sum_args = (struct SumArgs *)args; - return (void *)(size_t)Sum(sum_args); -} - -int main(int argc, char **argv) { - /* - * TODO: - * threads_num by command line arguments - * array_size by command line arguments - * seed by command line arguments - */ - - uint32_t threads_num = 0; - uint32_t array_size = 0; - uint32_t seed = 0; - pthread_t threads[threads_num]; - - /* - * TODO: - * your code here - * Generate array here - */ - - int *array = malloc(sizeof(int) * array_size); - - struct SumArgs args[threads_num]; - for (uint32_t i = 0; i < threads_num; i++) { - if (pthread_create(&threads[i], NULL, ThreadSum, (void *)&args)) { - printf("Error: pthread_create failed!\n"); - return 1; - } - } - - int total_sum = 0; - for (uint32_t i = 0; i < threads_num; i++) { - int sum = 0; - pthread_join(threads[i], (void **)&sum); - total_sum += sum; - } - - free(array); - printf("Total: %d\n", total_sum); - return 0; -} +#include +#include +#include +#include + +#include "utils.h" +#include "sum.h" + +#include + +#include + +void *ThreadSum(void *args) { + struct SumArgs *sum_args = (struct SumArgs *)args; + unsigned long long int *result = malloc(sizeof(unsigned long long int)); + *result = Sum(sum_args); + return (void *)result; +} + +int main(int argc, char **argv) { + + uint32_t threads_num = -1; + uint32_t seed = -1; + uint32_t array_size = -1; + + + + while (true) { + int current_optind = optind ? optind : 1; + + static struct option options[] = { + {"threads_num", required_argument, 0, 0}, + {"seed", required_argument, 0, 0}, + {"array_size", required_argument, 0, 0}, + {0, 0, 0, 0} + }; + + int option_index = 0; + int c = getopt_long(argc, argv, "", options, &option_index); + + if (c == -1) break; + + switch (c) { + case 0: + switch (option_index) { + case 0: + threads_num = atoi(optarg); + if (threads_num <= 0) { + printf("threads_num must be a positive number\n"); + return 1; + } + break; + case 1: + seed = atoi(optarg); + if (seed <= 0) { + printf("seed must be a positive number\n"); + return 1; + } + break; + case 2: + array_size = atoi(optarg); + if (array_size <= 0) { + printf("array_size must be a positive number\n"); + return 1; + } + break; + default: + printf("Index %d is out of options\n", option_index); + } + break; + + case '?': + break; + + default: + printf("getopt returned character code 0%o?\n", c); + } + } + + if (optind < argc) { + printf("Has at least one no option argument\n"); + return 1; + } + + if (threads_num == -1 || seed == -1 || array_size == -1) { + printf("Usage: %s --threads_num \"num\" --seed \"num\" -- array_size \"num\" \n", + argv[0]); + return 1; + } + + pthread_t threads[threads_num]; + int *array = malloc(sizeof(int) * array_size); + GenerateArray(array, array_size, seed); + + struct SumArgs args[threads_num]; + int chunk_size = array_size / threads_num; + + clock_t start_time = clock(); + + for (uint32_t i = 0; i < threads_num; i++) { + args[i].array = array; + args[i].begin = i * chunk_size; + args[i].end = (i + 1) * chunk_size; + if (i == threads_num - 1) { + args[i].end = array_size; + } + + if (pthread_create(&threads[i], NULL, ThreadSum, (void *)&args[i])) { + printf("Error: pthread_create failed!\n"); + return 1; + } + } + + unsigned long long int total_sum = 0; + for (uint32_t i = 0; i < threads_num; i++) { + unsigned long long int *sum; + pthread_join(threads[i], (void **)&sum); + total_sum += *sum; + //free(sum); + } + + clock_t end_time = clock(); + double time_taken = (double)(end_time - start_time) / CLOCKS_PER_SEC; + + free(array); + printf("Total: %llu\n", total_sum); + printf("Time taken to calculate sum: %.6f seconds\n", time_taken); + return 0; +} \ No newline at end of file diff --git a/lab4/src/parallel_sum.o b/lab4/src/parallel_sum.o new file mode 100644 index 000000000..f72dccb35 Binary files /dev/null and b/lab4/src/parallel_sum.o differ diff --git a/lab4/src/process_memory b/lab4/src/process_memory new file mode 100644 index 000000000..571e0d8f7 Binary files /dev/null and b/lab4/src/process_memory differ diff --git a/lab4/src/process_memory.c b/lab4/src/process_memory.c old mode 100755 new mode 100644 index 64b6b2b16..e502d3f3b --- a/lab4/src/process_memory.c +++ b/lab4/src/process_memory.c @@ -1,53 +1,53 @@ - -/* Program to display address information about the process */ -/* Adapted from Gray, J., program 1.4 */ -#include -#include -#include -#include -#include - -/* Below is a macro definition */ -#define SHW_ADR(ID, I) (printf("ID %s \t is at virtual address: %8X\n", ID, &I)) - -extern int etext, edata, end; /* Global variables for process - memory */ - -char *cptr = "This message is output by the function showit()\n"; /* Static */ -char buffer1[25]; -int showit(); /* Function prototype */ - -main() { - int i = 0; /* Automatic variable */ - - /* Printing addressing information */ - printf("\nAddress etext: %8X \n", &etext); - printf("Address edata: %8X \n", &edata); - printf("Address end : %8X \n", &end); - - SHW_ADR("main", main); - SHW_ADR("showit", showit); - SHW_ADR("cptr", cptr); - SHW_ADR("buffer1", buffer1); - SHW_ADR("i", i); - strcpy(buffer1, "A demonstration\n"); /* Library function */ - write(1, buffer1, strlen(buffer1) + 1); /* System call */ - showit(cptr); - -} /* end of main function */ - -/* A function follows */ -int showit(p) char *p; -{ - char *buffer2; - SHW_ADR("buffer2", buffer2); - if ((buffer2 = (char *)malloc((unsigned)(strlen(p) + 1))) != NULL) { - printf("Alocated memory at %X\n", buffer2); - strcpy(buffer2, p); /* copy the string */ - printf("%s", buffer2); /* Didplay the string */ - free(buffer2); /* Release location */ - } else { - printf("Allocation error\n"); - exit(1); - } -} + +/* Program to display address information about the process */ +/* Adapted from Gray, J., program 1.4 */ +#include +#include +#include +#include +#include + +/* Below is a macro definition */ +#define SHW_ADR(ID, I) (printf("ID %s \t is at virtual address: %8X\n", ID, &I)) + +extern int etext, edata, end; /* Global variables for process + memory */ + +char *cptr = "This message is output by the function showit()\n"; /* Static */ +char buffer1[25]; +int showit(); /* Function prototype */ + +main() { + int i = 0; /* Automatic variable */ + + /* Printing addressing information */ + printf("\nAddress etext: %8X \n", &etext); + printf("Address edata: %8X \n", &edata); + printf("Address end : %8X \n", &end); + + SHW_ADR("main", main); + SHW_ADR("showit", showit); + SHW_ADR("cptr", cptr); + SHW_ADR("buffer1", buffer1); + SHW_ADR("i", i); + strcpy(buffer1, "A demonstration\n"); /* Library function */ + write(1, buffer1, strlen(buffer1) + 1); /* System call */ + showit(cptr); + +} /* end of main function */ + +/* A function follows */ +int showit(p) char *p; +{ + char *buffer2; + SHW_ADR("buffer2", buffer2); + if ((buffer2 = (char *)malloc((unsigned)(strlen(p) + 1))) != NULL) { + printf("Alocated memory at %X\n", buffer2); + strcpy(buffer2, p); /* copy the string */ + printf("%s", buffer2); /* Didplay the string */ + free(buffer2); /* Release location */ + } else { + printf("Allocation error\n"); + exit(1); + } +} diff --git a/lab4/src/sum.c b/lab4/src/sum.c new file mode 100644 index 000000000..36d287938 --- /dev/null +++ b/lab4/src/sum.c @@ -0,0 +1,11 @@ +#include "sum.h" + +unsigned long long int Sum(struct SumArgs *args) { + unsigned long long int sum = 0; + + for (int i = args->begin; i < args->end; i++) { + sum += args->array[i]; + } + + return sum; +} \ No newline at end of file diff --git a/lab4/src/sum.h b/lab4/src/sum.h new file mode 100644 index 000000000..146de4212 --- /dev/null +++ b/lab4/src/sum.h @@ -0,0 +1,14 @@ +#ifndef SUM_H +#define SUM_H + +#include + +struct SumArgs { + int *array; // Указатель на массив + int begin; // Начальный индекс + int end; // Конечный индекс +}; + +unsigned long long int Sum(struct SumArgs *args); + +#endif // SUM_H \ No newline at end of file diff --git a/lab4/src/sum.o b/lab4/src/sum.o new file mode 100644 index 000000000..8b4a8ad68 Binary files /dev/null and b/lab4/src/sum.o differ diff --git a/lab4/src/utils.c b/lab4/src/utils.c new file mode 100644 index 000000000..d53f38dd1 --- /dev/null +++ b/lab4/src/utils.c @@ -0,0 +1,10 @@ +#include "utils.h" + +#include +#include +void GenerateArray(int *array, unsigned int array_size, unsigned int seed) { + srand(seed); + for (int i = 0; i < array_size; i++) { + array[i] = rand(); + } +} diff --git a/lab4/src/utils.h b/lab4/src/utils.h new file mode 100644 index 000000000..262a24e0f --- /dev/null +++ b/lab4/src/utils.h @@ -0,0 +1,11 @@ +#ifndef UTILS_H +#define UTILS_H + +struct MinMax { + int min; + int max; +}; + +void GenerateArray(int *array, unsigned int array_size, unsigned int seed); + +#endif diff --git a/lab4/src/utils.o b/lab4/src/utils.o new file mode 100644 index 000000000..53c641244 Binary files /dev/null and b/lab4/src/utils.o differ diff --git a/lab4/src/zombie.c b/lab4/src/zombie.c new file mode 100644 index 000000000..f59ad2427 --- /dev/null +++ b/lab4/src/zombie.c @@ -0,0 +1,33 @@ +#include +#include +#include +#include +#include + +int main() { + pid_t pid; + + for (int i = 0; i < 5; i++) { + pid = fork(); + + if (pid < 0) { + perror("Fork failed"); + exit(1); + } else if (pid == 0) { + printf("Дочерний процесс %d с PID %d\n", i + 1, getpid()); + sleep(1); + exit(0); + } + } + + printf("Родительский процесс с PID %d\n", getpid()); + + sleep(1); + + printf("Теперь в системе должны быть зомби-процессы.\n"); + printf("Нажмите Enter, чтобы завершить родительский процесс и очистить зомби.\n"); + getchar(); + + printf("Родительский процесс завершен.\n"); + return 0; +} \ No newline at end of file diff --git a/lab5/src/dead b/lab5/src/dead new file mode 100644 index 000000000..ac5541576 Binary files /dev/null and b/lab5/src/dead differ diff --git a/lab5/src/deadlock.c b/lab5/src/deadlock.c new file mode 100644 index 000000000..6b821f8db --- /dev/null +++ b/lab5/src/deadlock.c @@ -0,0 +1,53 @@ +#include +#include +#include +#include // Необходимо для sleep + + +pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER; +pthread_mutex_t mutex2 = PTHREAD_MUTEX_INITIALIZER; + +void* thread_func1(void* arg) { + pthread_mutex_lock(&mutex1); + printf("Thread 1 locked mutex1\n"); + + sleep(1); // Имитация долгой работы + + pthread_mutex_lock(&mutex2); + printf("Thread 1 locked mutex2\n"); + + pthread_mutex_unlock(&mutex2); + pthread_mutex_unlock(&mutex1); + + return NULL; +} + +void* thread_func2(void* arg) { + pthread_mutex_lock(&mutex2); + printf("Thread 2 locked mutex2\n"); + + sleep(1); // Имитация долгой работы + + pthread_mutex_lock(&mutex1); + printf("Thread 2 locked mutex1\n"); + + pthread_mutex_unlock(&mutex1); + pthread_mutex_unlock(&mutex2); + + return NULL; +} + +int main() { + pthread_t thread1, thread2; + + pthread_create(&thread1, NULL, thread_func1, NULL); + pthread_create(&thread2, NULL, thread_func2, NULL); + + pthread_join(thread1, NULL); + pthread_join(thread2, NULL); + + pthread_mutex_destroy(&mutex1); + pthread_mutex_destroy(&mutex2); + + return 0; +} \ No newline at end of file diff --git a/lab5/src/f b/lab5/src/f new file mode 100644 index 000000000..8d2151249 Binary files /dev/null and b/lab5/src/f differ diff --git a/lab5/src/factorial.c b/lab5/src/factorial.c new file mode 100644 index 000000000..74af96002 --- /dev/null +++ b/lab5/src/factorial.c @@ -0,0 +1,62 @@ +#include +#include +#include + +long long result = 1; +pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + +typedef struct { + int start; + int end; + int mod; +} ThreadArgs; + +void* factorial_part(void* args) { + ThreadArgs* data = (ThreadArgs*)args; + long long partial_result = 1; + + for (int i = data->start; i <= data->end; i++) { + partial_result = (partial_result * i) % data->mod; + } + + pthread_mutex_lock(&mutex); + result = (result * partial_result) % data->mod; + pthread_mutex_unlock(&mutex); + + return NULL; +} + +int main(int argc, char* argv[]) { + if (argc != 4) { + printf("Usage: %s k pnum mod\n", argv[0]); + return 1; + } + + int k = atoi(argv[1]); + int pnum = atoi(argv[2]); + int mod = atoi(argv[3]); + + pthread_t threads[pnum]; + ThreadArgs args[pnum]; + + int range = k / pnum; + for (int i = 0; i < pnum; i++) { + args[i].start = i * range + 1; + args[i].end = (i == pnum - 1) ? k : (i + 1) * range; + args[i].mod = mod; + + if (pthread_create(&threads[i], NULL, factorial_part, &args[i]) != 0) { + perror("pthread_create"); + return 1; + } + } + + for (int i = 0; i < pnum; i++) { + pthread_join(threads[i], NULL); + } + + printf("Factorial %d! mod %d = %lld\n", k, mod, result); + pthread_mutex_destroy(&mutex); + + return 0; +} \ No newline at end of file diff --git a/lab5/src/mutex b/lab5/src/mutex new file mode 100644 index 000000000..631517fd7 Binary files /dev/null and b/lab5/src/mutex differ diff --git a/lab5/src/mutex.c b/lab5/src/mutex.c old mode 100755 new mode 100644 index 4e86390db..41a6eeb19 --- a/lab5/src/mutex.c +++ b/lab5/src/mutex.c @@ -1,92 +1,90 @@ -/******************************************************** - * An example source module to accompany... - * - * "Using POSIX Threads: Programming with Pthreads" - * by Brad nichols, Dick Buttlar, Jackie Farrell - * O'Reilly & Associates, Inc. - * Modified by A.Kostin - ******************************************************** - * mutex.c - * - * Simple multi-threaded example with a mutex lock. - */ -#include -#include -#include -#include - -void do_one_thing(int *); -void do_another_thing(int *); -void do_wrap_up(int); -int common = 0; /* A shared variable for two threads */ -int r1 = 0, r2 = 0, r3 = 0; -pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER; - -int main() { - pthread_t thread1, thread2; - - if (pthread_create(&thread1, NULL, (void *)do_one_thing, - (void *)&common) != 0) { - perror("pthread_create"); - exit(1); - } - - if (pthread_create(&thread2, NULL, (void *)do_another_thing, - (void *)&common) != 0) { - perror("pthread_create"); - exit(1); - } - - if (pthread_join(thread1, NULL) != 0) { - perror("pthread_join"); - exit(1); - } - - if (pthread_join(thread2, NULL) != 0) { - perror("pthread_join"); - exit(1); - } - - do_wrap_up(common); - - return 0; -} - -void do_one_thing(int *pnum_times) { - int i, j, x; - unsigned long k; - int work; - for (i = 0; i < 50; i++) { - // pthread_mutex_lock(&mut); - printf("doing one thing\n"); - work = *pnum_times; - printf("counter = %d\n", work); - work++; /* increment, but not write */ - for (k = 0; k < 500000; k++) - ; /* long cycle */ - *pnum_times = work; /* write back */ - // pthread_mutex_unlock(&mut); - } -} - -void do_another_thing(int *pnum_times) { - int i, j, x; - unsigned long k; - int work; - for (i = 0; i < 50; i++) { - // pthread_mutex_lock(&mut); - printf("doing another thing\n"); - work = *pnum_times; - printf("counter = %d\n", work); - work++; /* increment, but not write */ - for (k = 0; k < 500000; k++) - ; /* long cycle */ - *pnum_times = work; /* write back */ - // pthread_mutex_unlock(&mut); - } -} - -void do_wrap_up(int counter) { - int total; - printf("All done, counter = %d\n", counter); -} +/******************************************************** + * An example source module to accompany... + * + * "Using POSIX Threads: Programming with Pthreads" + * by Brad nichols, Dick Buttlar, Jackie Farrell + * O'Reilly & Associates, Inc. + * Modified by A.Kostin + ******************************************************** + * mutex.c + * + * Simple multi-threaded example with a mutex lock. + */ +#include +#include +#include +#include + +void do_one_thing(int *); +void do_another_thing(int *); +void do_wrap_up(int); +int common = 0; /* A shared variable for two threads */ +int r1 = 0, r2 = 0, r3 = 0; +pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER; + +int main() { + pthread_t thread1, thread2; + + if (pthread_create(&thread1, NULL, (void *)do_one_thing, (void *)&common) != 0) { + perror("pthread_create"); + exit(1); + } + + if (pthread_create(&thread2, NULL, (void *)do_another_thing, (void *)&common) != 0) { + perror("pthread_create"); + exit(1); + } + + if (pthread_join(thread1, NULL) != 0) { + perror("pthread_join"); + exit(1); + } + + if (pthread_join(thread2, NULL) != 0) { + perror("pthread_join"); + exit(1); + } + + do_wrap_up(common); + + return 0; +} + +void do_one_thing(int *pnum_times) { + int i, j, x; + unsigned long k; + int work; + for (i = 0; i < 50; i++) { + pthread_mutex_lock(&mut); + printf("doing one thing\n"); + work = *pnum_times; + printf("counter = %d\n", work); + work++; /* increment, but not write */ + for (k = 0; k < 500000; k++) + ; /* long cycle */ + *pnum_times = work; /* write back */ + pthread_mutex_unlock(&mut); + } +} + +void do_another_thing(int *pnum_times) { + int i, j, x; + unsigned long k; + int work; + for (i = 0; i < 50; i++) { + pthread_mutex_lock(&mut); + printf("doing another thing\n"); + work = *pnum_times; + printf("counter = %d\n", work); + work++; /* increment, but not write */ + for (k = 0; k < 500000; k++) + ; /* long cycle */ + *pnum_times = work; /* write back */ + pthread_mutex_unlock(&mut); + } +} + +void do_wrap_up(int counter) { + int total; + printf("All done, counter = %d\n", counter); +} diff --git a/lab5/src/no_mutex b/lab5/src/no_mutex new file mode 100644 index 000000000..fc086af36 Binary files /dev/null and b/lab5/src/no_mutex differ diff --git a/lab6/src/MultModulo.c b/lab6/src/MultModulo.c new file mode 100644 index 000000000..ec867fce3 --- /dev/null +++ b/lab6/src/MultModulo.c @@ -0,0 +1,14 @@ +#include "MultModulo.h" + +uint64_t MultModulo(uint64_t a, uint64_t b, uint64_t mod) { + uint64_t result = 0; + a = a % mod; + while (b > 0) { + if (b % 2 == 1) + result = (result + a) % mod; + a = (a * 2) % mod; + b /= 2; + } + + return result % mod; +} \ No newline at end of file diff --git a/lab6/src/MultModulo.h b/lab6/src/MultModulo.h new file mode 100644 index 000000000..d02ba1ff1 --- /dev/null +++ b/lab6/src/MultModulo.h @@ -0,0 +1,3 @@ +#include + +uint64_t MultModulo(uint64_t a, uint64_t b, uint64_t mod); \ No newline at end of file diff --git a/lab6/src/MultModulo.o b/lab6/src/MultModulo.o new file mode 100644 index 000000000..152f46dfa Binary files /dev/null and b/lab6/src/MultModulo.o differ diff --git a/lab6/src/client b/lab6/src/client new file mode 100644 index 000000000..20d5c20ba Binary files /dev/null and b/lab6/src/client differ diff --git a/lab6/src/client.c b/lab6/src/client.c old mode 100755 new mode 100644 index 91b35af32..06d316e23 --- a/lab6/src/client.c +++ b/lab6/src/client.c @@ -1,164 +1,227 @@ -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -struct Server { - char ip[255]; - int port; -}; - -uint64_t MultModulo(uint64_t a, uint64_t b, uint64_t mod) { - uint64_t result = 0; - a = a % mod; - while (b > 0) { - if (b % 2 == 1) - result = (result + a) % mod; - a = (a * 2) % mod; - b /= 2; - } - - return result % mod; -} - -bool ConvertStringToUI64(const char *str, uint64_t *val) { - char *end = NULL; - unsigned long long i = strtoull(str, &end, 10); - if (errno == ERANGE) { - fprintf(stderr, "Out of uint64_t range: %s\n", str); - return false; - } - - if (errno != 0) - return false; - - *val = i; - return true; -} - -int main(int argc, char **argv) { - uint64_t k = -1; - uint64_t mod = -1; - char servers[255] = {'\0'}; // TODO: explain why 255 - - while (true) { - int current_optind = optind ? optind : 1; - - static struct option options[] = {{"k", required_argument, 0, 0}, - {"mod", required_argument, 0, 0}, - {"servers", required_argument, 0, 0}, - {0, 0, 0, 0}}; - - int option_index = 0; - int c = getopt_long(argc, argv, "", options, &option_index); - - if (c == -1) - break; - - switch (c) { - case 0: { - switch (option_index) { - case 0: - ConvertStringToUI64(optarg, &k); - // TODO: your code here - break; - case 1: - ConvertStringToUI64(optarg, &mod); - // TODO: your code here - break; - case 2: - // TODO: your code here - memcpy(servers, optarg, strlen(optarg)); - break; - default: - printf("Index %d is out of options\n", option_index); - } - } break; - - case '?': - printf("Arguments error\n"); - break; - default: - fprintf(stderr, "getopt returned character code 0%o?\n", c); - } - } - - if (k == -1 || mod == -1 || !strlen(servers)) { - fprintf(stderr, "Using: %s --k 1000 --mod 5 --servers /path/to/file\n", - argv[0]); - return 1; - } - - // TODO: for one server here, rewrite with servers from file - unsigned int servers_num = 1; - struct Server *to = malloc(sizeof(struct Server) * servers_num); - // TODO: delete this and parallel work between servers - to[0].port = 20001; - memcpy(to[0].ip, "127.0.0.1", sizeof("127.0.0.1")); - - // TODO: work continiously, rewrite to make parallel - for (int i = 0; i < servers_num; i++) { - struct hostent *hostname = gethostbyname(to[i].ip); - if (hostname == NULL) { - fprintf(stderr, "gethostbyname failed with %s\n", to[i].ip); - exit(1); - } - - struct sockaddr_in server; - server.sin_family = AF_INET; - server.sin_port = htons(to[i].port); - server.sin_addr.s_addr = *((unsigned long *)hostname->h_addr); - - int sck = socket(AF_INET, SOCK_STREAM, 0); - if (sck < 0) { - fprintf(stderr, "Socket creation failed!\n"); - exit(1); - } - - if (connect(sck, (struct sockaddr *)&server, sizeof(server)) < 0) { - fprintf(stderr, "Connection failed\n"); - exit(1); - } - - // TODO: for one server - // parallel between servers - uint64_t begin = 1; - uint64_t end = k; - - char task[sizeof(uint64_t) * 3]; - memcpy(task, &begin, sizeof(uint64_t)); - memcpy(task + sizeof(uint64_t), &end, sizeof(uint64_t)); - memcpy(task + 2 * sizeof(uint64_t), &mod, sizeof(uint64_t)); - - if (send(sck, task, sizeof(task), 0) < 0) { - fprintf(stderr, "Send failed\n"); - exit(1); - } - - char response[sizeof(uint64_t)]; - if (recv(sck, response, sizeof(response), 0) < 0) { - fprintf(stderr, "Recieve failed\n"); - exit(1); - } - - // TODO: from one server - // unite results - uint64_t answer = 0; - memcpy(&answer, response, sizeof(uint64_t)); - printf("answer: %llu\n", answer); - - close(sck); - } - free(to); - - return 0; -} +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include "MultModulo.h" + +struct Server { + char ip[255]; + int port; +}; + + + +bool is_file_exist(const char *fileName) +{ + FILE *file; + if (file = fopen(fileName, "r")) { + fclose(file); + return true; + } else { + return false; + } +} + + +bool ConvertStringToUI64(const char *str, uint64_t *val) { + char *end = NULL; + unsigned long long i = strtoull(str, &end, 10); + if (errno == ERANGE) { + fprintf(stderr, "Out of uint64_t range: %s\n", str); + return false; + } + + if (errno != 0) + return false; + + *val = i; + return true; +} + +int main(int argc, char **argv) { + uint64_t k = -1; + uint64_t mod = -1; + char servers[255] = {'\0'}; // max length of UTF-8 filename in UNIX + + while (true) { + int current_optind = optind ? optind : 1; + + static struct option options[] = {{"k", required_argument, 0, 0}, + {"mod", required_argument, 0, 0}, + {"servers", required_argument, 0, 0}, + {0, 0, 0, 0}}; + + int option_index = 0; + int c = getopt_long(argc, argv, "", options, &option_index); + + if (c == -1) + break; + + switch (c) { + case 0: { + switch (option_index) { + case 0: + ConvertStringToUI64(optarg, &k); + // TODO: your code here + if (k <= 0) + { + printf("Invalid arguments (k)!\n"); + exit(EXIT_FAILURE); + } + break; + case 1: + ConvertStringToUI64(optarg, &mod); + if (mod <= 0) + { + printf("Invalid arguments (mod)!\n"); + exit(EXIT_FAILURE); + } + // TODO: your code here + break; + case 2: + // TODO: your code here + if (is_file_exist(optarg)) + { + memcpy(servers, optarg, strlen(optarg)); + } + else + { + printf("Invalid arguments (servers)!\n"); + exit(EXIT_FAILURE); + } + break; + default: + printf("Index %d is out of options\n", option_index); + } + } break; + + case '?': + printf("Arguments error\n"); + break; + default: + fprintf(stderr, "getopt returned character code 0%o?\n", c); + } + } + + if (k == -1 || mod == -1 || !strlen(servers)) { + fprintf(stderr, "Using: %s --k 1000 --mod 5 --servers /path/to/file\n", + argv[0]); + return 1; + } + + // // TODO: for one server here, rewrite with servers from file + // unsigned int servers_num = 1; + // struct Server *to = malloc(sizeof(struct Server) * servers_num); + // // TODO: delete this and parallel work between servers + // to[0].port = 20001; + // memcpy(to[0].ip, "127.0.0.1", sizeof("127.0.0.1")); + + unsigned int servers_num = 0; + FILE* fp; + fp = fopen(servers, "r"); + while (!feof(fp)) + { + char test1[255]; + char test2[255]; + fscanf(fp, "%s : %s\n", test1, test2); + servers_num++; + } + struct Server *to = malloc(sizeof(struct Server) * servers_num); + fseek(fp, 0L, SEEK_SET); + + int index = 0; + while (!feof(fp)) + { + fscanf(fp, "%s : %d\n", to[index].ip, &to[index].port); + printf("ip: %s, port: %d\n", to[index].ip, to[index].port); + index++; + } + fclose(fp); + + int factorial_part = k / servers_num; + uint64_t result = 1; + int* sck = malloc(sizeof(int) * servers_num);//Выделяется память для массива сокетов `sck`. + + // TODO: work continiously, rewrite to make parallel + // цикл для подключения к каждому серверу последовательно. + for (int i = 0; i < servers_num; i++) { + struct hostent *hostname = gethostbyname(to[i].ip); + if (hostname == NULL) { + fprintf(stderr, "gethostbyname failed with %s\n", to[i].ip); + exit(1); + } + //структура `sockaddr_in` с информацией о сервере. + struct sockaddr_in server; + server.sin_family = AF_INET; + server.sin_port = htons(to[i].port); + server.sin_addr.s_addr = *((unsigned long *)hostname->h_addr); + + int sck = socket(AF_INET, SOCK_STREAM, 0); + if (sck < 0) { + fprintf(stderr, "Socket creation failed!\n"); + exit(1); + } + + if (connect(sck, (struct sockaddr *)&server, sizeof(server)) < 0) { + fprintf(stderr, "Connection failed\n"); + exit(1); + } + + // TODO: for one server + // parallel between servers + // uint64_t begin = 1; + // uint64_t end = k; + + uint64_t begin = (i*factorial_part) + 1; + uint64_t end; + if (i != servers_num - 1) + { + end = (i + 1)*factorial_part; + } + else + { + end = k; + } + + + char task[sizeof(uint64_t) * 3]; + memcpy(task, &begin, sizeof(uint64_t)); + memcpy(task + sizeof(uint64_t), &end, sizeof(uint64_t)); + memcpy(task + 2 * sizeof(uint64_t), &mod, sizeof(uint64_t)); + + //Отправляется сообщение `task` серверу с помощью функции `send`. + if (send(sck, task, sizeof(task), 0) < 0) { + fprintf(stderr, "Send failed\n"); + exit(1); + } + + //Получается ответ от сервера с помощью функции `recv` + char response[sizeof(uint64_t)]; + if (recv(sck, response, sizeof(response), 0) < 0) { + fprintf(stderr, "Recieve failed\n"); + exit(1); + } + + // TODO: from one server + // unite results + uint64_t answer = 0; + memcpy(&answer, response, sizeof(uint64_t)); + result = MultModulo(result, answer, mod); + // printf("answer: %llu\n", answer); + + close(sck); + } + printf("answer: %lu\n", result); + free(to); + + return 0; +} \ No newline at end of file diff --git a/lab6/src/libMultModulo.a b/lab6/src/libMultModulo.a new file mode 100644 index 000000000..eb88409e8 Binary files /dev/null and b/lab6/src/libMultModulo.a differ diff --git a/lab6/src/makefile b/lab6/src/makefile new file mode 100644 index 000000000..7bca1ffd6 --- /dev/null +++ b/lab6/src/makefile @@ -0,0 +1,16 @@ +CC=gcc +CFLAGS= -I. + +all : server client + +server : server.c library.o library.h + $(CC) -pthread -o server server.c library.o $(CFLAGS) + +client : client.c library.o library.h + $(CC) -pthread -o client client.c library.o $(CFLAGS) + +library.o : library.h + $(CC) -o library.o -c library.c $(CFLAGS) + +clean : + rm server client library.o \ No newline at end of file diff --git a/lab6/src/server b/lab6/src/server new file mode 100644 index 000000000..c7f814042 Binary files /dev/null and b/lab6/src/server differ diff --git a/lab6/src/server.c b/lab6/src/server.c old mode 100755 new mode 100644 index 4c5f53abb..38800d981 --- a/lab6/src/server.c +++ b/lab6/src/server.c @@ -1,196 +1,213 @@ -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "pthread.h" - -struct FactorialArgs { - uint64_t begin; - uint64_t end; - uint64_t mod; -}; - -uint64_t MultModulo(uint64_t a, uint64_t b, uint64_t mod) { - uint64_t result = 0; - a = a % mod; - while (b > 0) { - if (b % 2 == 1) - result = (result + a) % mod; - a = (a * 2) % mod; - b /= 2; - } - - return result % mod; -} - -uint64_t Factorial(const struct FactorialArgs *args) { - uint64_t ans = 1; - - // TODO: your code here - - return ans; -} - -void *ThreadFactorial(void *args) { - struct FactorialArgs *fargs = (struct FactorialArgs *)args; - return (void *)(uint64_t *)Factorial(fargs); -} - -int main(int argc, char **argv) { - int tnum = -1; - int port = -1; - - while (true) { - int current_optind = optind ? optind : 1; - - static struct option options[] = {{"port", required_argument, 0, 0}, - {"tnum", required_argument, 0, 0}, - {0, 0, 0, 0}}; - - int option_index = 0; - int c = getopt_long(argc, argv, "", options, &option_index); - - if (c == -1) - break; - - switch (c) { - case 0: { - switch (option_index) { - case 0: - port = atoi(optarg); - // TODO: your code here - break; - case 1: - tnum = atoi(optarg); - // TODO: your code here - break; - default: - printf("Index %d is out of options\n", option_index); - } - } break; - - case '?': - printf("Unknown argument\n"); - break; - default: - fprintf(stderr, "getopt returned character code 0%o?\n", c); - } - } - - if (port == -1 || tnum == -1) { - fprintf(stderr, "Using: %s --port 20001 --tnum 4\n", argv[0]); - return 1; - } - - int server_fd = socket(AF_INET, SOCK_STREAM, 0); - if (server_fd < 0) { - fprintf(stderr, "Can not create server socket!"); - return 1; - } - - struct sockaddr_in server; - server.sin_family = AF_INET; - server.sin_port = htons((uint16_t)port); - server.sin_addr.s_addr = htonl(INADDR_ANY); - - int opt_val = 1; - setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt_val, sizeof(opt_val)); - - int err = bind(server_fd, (struct sockaddr *)&server, sizeof(server)); - if (err < 0) { - fprintf(stderr, "Can not bind to socket!"); - return 1; - } - - err = listen(server_fd, 128); - if (err < 0) { - fprintf(stderr, "Could not listen on socket\n"); - return 1; - } - - printf("Server listening at %d\n", port); - - while (true) { - struct sockaddr_in client; - socklen_t client_len = sizeof(client); - int client_fd = accept(server_fd, (struct sockaddr *)&client, &client_len); - - if (client_fd < 0) { - fprintf(stderr, "Could not establish new connection\n"); - continue; - } - - while (true) { - unsigned int buffer_size = sizeof(uint64_t) * 3; - char from_client[buffer_size]; - int read = recv(client_fd, from_client, buffer_size, 0); - - if (!read) - break; - if (read < 0) { - fprintf(stderr, "Client read failed\n"); - break; - } - if (read < buffer_size) { - fprintf(stderr, "Client send wrong data format\n"); - break; - } - - pthread_t threads[tnum]; - - uint64_t begin = 0; - uint64_t end = 0; - uint64_t mod = 0; - memcpy(&begin, from_client, sizeof(uint64_t)); - memcpy(&end, from_client + sizeof(uint64_t), sizeof(uint64_t)); - memcpy(&mod, from_client + 2 * sizeof(uint64_t), sizeof(uint64_t)); - - fprintf(stdout, "Receive: %llu %llu %llu\n", begin, end, mod); - - struct FactorialArgs args[tnum]; - for (uint32_t i = 0; i < tnum; i++) { - // TODO: parallel somehow - args[i].begin = 1; - args[i].end = 1; - args[i].mod = mod; - - if (pthread_create(&threads[i], NULL, ThreadFactorial, - (void *)&args[i])) { - printf("Error: pthread_create failed!\n"); - return 1; - } - } - - uint64_t total = 1; - for (uint32_t i = 0; i < tnum; i++) { - uint64_t result = 0; - pthread_join(threads[i], (void **)&result); - total = MultModulo(total, result, mod); - } - - printf("Total: %llu\n", total); - - char buffer[sizeof(total)]; - memcpy(buffer, &total, sizeof(total)); - err = send(client_fd, buffer, sizeof(total), 0); - if (err < 0) { - fprintf(stderr, "Can't send data to client\n"); - break; - } - } - - shutdown(client_fd, SHUT_RDWR); - close(client_fd); - } - - return 0; -} +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "pthread.h" +#include "MultModulo.h" + +pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER; + +struct FactorialArgs { + uint64_t begin; + uint64_t end; + uint64_t mod; +}; + + + +uint64_t Factorial(const struct FactorialArgs *args) { + uint64_t ans = 1; + // TODO: your code here + int start = args->begin; + int end = args->end; + int mod = args->mod; + pthread_mutex_lock(&mut); + + for (int i = start; i <= end; i++) { + ans = MultModulo(ans, i, mod);} + + pthread_mutex_unlock(&mut); + + return ans; +} + +void *ThreadFactorial(void *args) { + struct FactorialArgs *fargs = (struct FactorialArgs *)args; + return (void *)(uint64_t *)Factorial(fargs); +} + +int main(int argc, char **argv) { + int tnum = -1; + int port = -1; + + while (true) { + int current_optind = optind ? optind : 1; + + static struct option options[] = {{"port", required_argument, 0, 0}, + {"tnum", required_argument, 0, 0}, + {0, 0, 0, 0}}; + + int option_index = 0; + int c = getopt_long(argc, argv, "", options, &option_index); + + if (c == -1) + break; + + switch (c) { + case 0: { + switch (option_index) { + case 0: + port = atoi(optarg); + // TODO: your code here + if (port <= 0) + { + printf("Invalid arguments (port)!\n"); + exit(EXIT_FAILURE); + } + break; + case 1: + tnum = atoi(optarg); + if (tnum <= 0) + { + printf("Invalid arguments (tnum)!\n"); + exit(EXIT_FAILURE); + } + // TODO: your code here + break; + default: + printf("Index %d is out of options\n", option_index); + } + } break; + + case '?': + printf("Unknown argument\n"); + break; + default: + fprintf(stderr, "getopt returned character code 0%o?\n", c); + } + } + + if (port == -1 || tnum == -1) { + fprintf(stderr, "Using: %s --port 20001 --tnum 4\n", argv[0]); + return 1; + } + + int server_fd = socket(AF_INET, SOCK_STREAM, 0); + if (server_fd < 0) { + fprintf(stderr, "Can not create server socket!"); + return 1; + } + + struct sockaddr_in server; + server.sin_family = AF_INET; + server.sin_port = htons((uint16_t)port); + server.sin_addr.s_addr = htonl(INADDR_ANY); + + int opt_val = 1; + setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt_val, sizeof(opt_val)); + + int err = bind(server_fd, (struct sockaddr *)&server, sizeof(server)); + if (err < 0) { + fprintf(stderr, "Can not bind to socket!"); + return 1; + } + + err = listen(server_fd, 128); + if (err < 0) { + fprintf(stderr, "Could not listen on socket\n"); + return 1; + } + + printf("Server listening at %d\n", port); + + while (true) { + struct sockaddr_in client; + socklen_t client_len = sizeof(client); + int client_fd = accept(server_fd, (struct sockaddr *)&client, &client_len); + + if (client_fd < 0) { + fprintf(stderr, "Could not establish new connection\n"); + continue; + } + + while (true) { + unsigned int buffer_size = sizeof(uint64_t) * 3; + char from_client[buffer_size]; + int read = recv(client_fd, from_client, buffer_size, 0); + + if (!read) + break; + if (read < 0) { + fprintf(stderr, "Client read failed\n"); + break; + } + if (read < buffer_size) { + fprintf(stderr, "Client send wrong data format\n"); + break; + } + + pthread_t threads[tnum]; + + uint64_t begin = 0; + uint64_t end = 0; + uint64_t mod = 0; + memcpy(&begin, from_client, sizeof(uint64_t)); + memcpy(&end, from_client + sizeof(uint64_t), sizeof(uint64_t)); + memcpy(&mod, from_client + 2 * sizeof(uint64_t), sizeof(uint64_t)); + + fprintf(stdout, "Receive: %llu %llu %llu\n", begin, end, mod); + + struct FactorialArgs args[tnum]; + uint64_t step = (end - begin) / tnum; + for (uint32_t i = 0; i < tnum; i++) { + // TODO: parallel somehow + //args[i].begin = 1; + //args[i].end = 1; + args[i].mod = mod; + args[i].begin = begin + i * step; + if (i == tnum - 1) { + args[i].end = end+1; + } else { + args[i].end = args[i].begin + step; + } + + if (pthread_create(&threads[i], NULL, ThreadFactorial, + (void *)&args[i])) { + printf("Error: pthread_create failed!\n"); + return 1; + } + } + + uint64_t total = 1; + for (uint32_t i = 0; i < tnum; i++) { + uint64_t result = 0; + pthread_join(threads[i], (void **)&result); + total = MultModulo(total, result, mod); + } + + printf("Total: %llu\n", total); + + char buffer[sizeof(total)]; + memcpy(buffer, &total, sizeof(total)); + err = send(client_fd, buffer, sizeof(total), 0); + if (err < 0) { + fprintf(stderr, "Can't send data to client\n"); + break; + } + } + + shutdown(client_fd, SHUT_RDWR); + close(client_fd); + } + + return 0; +} diff --git a/lab6/src/servers.txt b/lab6/src/servers.txt new file mode 100644 index 000000000..e6e4fe3da --- /dev/null +++ b/lab6/src/servers.txt @@ -0,0 +1,2 @@ +127.0.0.1 : 20001 +127.0.0.1 : 20002 \ No newline at end of file diff --git a/lab7/src/makefile b/lab7/src/makefile new file mode 100644 index 000000000..89b569869 --- /dev/null +++ b/lab7/src/makefile @@ -0,0 +1,10 @@ +CC=gcc +CFLAGS=-I. + +all: + $(CC) -o tcpcl tcpclient.c + $(CC) -o tcpserv tcpserver.c + $(CC) -o udpcl udpclient.c + $(CC) -o udpserv udpserver.c +clean: + rm udpserv udpcl tcpserv tcpcl \ No newline at end of file diff --git a/lab7/src/tcpclient b/lab7/src/tcpclient new file mode 100644 index 000000000..6939da367 Binary files /dev/null and b/lab7/src/tcpclient differ diff --git a/lab7/src/tcpclient.c b/lab7/src/tcpclient.c old mode 100755 new mode 100644 index 44fb2f48b..aa8426433 --- a/lab7/src/tcpclient.c +++ b/lab7/src/tcpclient.c @@ -1,54 +1,122 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -#define BUFSIZE 100 -#define SADDR struct sockaddr -#define SIZE sizeof(struct sockaddr_in) - -int main(int argc, char *argv[]) { - int fd; - int nread; - char buf[BUFSIZE]; - struct sockaddr_in servaddr; - if (argc < 3) { - printf("Too few arguments \n"); - exit(1); - } - - if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { - perror("socket creating"); - exit(1); - } - - memset(&servaddr, 0, SIZE); - servaddr.sin_family = AF_INET; - - if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0) { - perror("bad address"); - exit(1); - } - - servaddr.sin_port = htons(atoi(argv[2])); - - if (connect(fd, (SADDR *)&servaddr, SIZE) < 0) { - perror("connect"); - exit(1); - } - - write(1, "Input message to send\n", 22); - while ((nread = read(0, buf, BUFSIZE)) > 0) { - if (write(fd, buf, nread) < 0) { - perror("write"); - exit(1); - } - } - - close(fd); - exit(0); -} +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SADDR struct sockaddr +#define SIZE sizeof(struct sockaddr_in) + +int main(int argc, char *argv[]) +{ + int bufsize = -1; + int port = -1; + char ip[255] = {'\0'}; + + while (true) + { + int current_optind = optind ? optind : 1; + + static struct option options[] = {{"bufsize", required_argument, 0, 0}, + {"ip", required_argument, 0, 0}, + {"port", required_argument, 0, 0}, + {0, 0, 0, 0}}; + + int option_index = 0; + int c = getopt_long(argc, argv, "", options, &option_index); + + if (c == -1) + break; + + switch (c) + { + case 0: + { + switch (option_index) + { + case 0: + bufsize = atoi(optarg); + if (bufsize < 1 || bufsize > 65535) + { + printf("bufsize should be an integer!\n"); + return -1; + } + break; + case 1: + memcpy(ip, optarg, strlen(optarg)); + break; + case 2: + port = atoi(optarg); + if (port < 1 || port > 65535) + { + printf("port should be an integer!\n"); + return -1; + } + break; + default: + printf("Index %d is out of options\n", option_index); + } + } + break; + + case '?': + printf("Unknown argument\n"); + break; + default: + fprintf(stderr, "getopt returned character code 0%o?\n", c); + } + } + + if (bufsize == -1 || port == -1 || strlen(ip) == 0) + { + fprintf(stderr, "Using: %s --bufsize 100 --ip 0.0.0.0 --port 10050\n", + argv[0]); + return 1; + } + + int fd; + int nread; + char buf[bufsize]; + struct sockaddr_in servaddr; + + if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) + { + perror("socket creating"); + exit(1); + } + + memset(&servaddr, 0, SIZE); + servaddr.sin_family = AF_INET; + + if (inet_pton(AF_INET, ip, &servaddr.sin_addr) <= 0) + { + perror("bad address"); + exit(1); + } + + servaddr.sin_port = htons(port); + + if (connect(fd, (SADDR *)&servaddr, SIZE) < 0) + { + perror("connect"); + exit(1); + } + + write(1, "Input message to send\n", 22); + while ((nread = read(0, buf, bufsize)) > 0) + { + if (write(fd, buf, nread) < 0) + { + perror("write"); + exit(1); + } + } + + close(fd); + exit(0); +} \ No newline at end of file diff --git a/lab7/src/tcpserver b/lab7/src/tcpserver new file mode 100644 index 000000000..4608af668 Binary files /dev/null and b/lab7/src/tcpserver differ diff --git a/lab7/src/tcpserver.c b/lab7/src/tcpserver.c old mode 100755 new mode 100644 index 01489864e..09c2f23ac --- a/lab7/src/tcpserver.c +++ b/lab7/src/tcpserver.c @@ -1,62 +1,130 @@ -#include -#include -#include -#include - -#include -#include -#include - -#define SERV_PORT 10050 -#define BUFSIZE 100 -#define SADDR struct sockaddr - -int main() { - const size_t kSize = sizeof(struct sockaddr_in); - - int lfd, cfd; - int nread; - char buf[BUFSIZE]; - struct sockaddr_in servaddr; - struct sockaddr_in cliaddr; - - if ((lfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { - perror("socket"); - exit(1); - } - - memset(&servaddr, 0, kSize); - servaddr.sin_family = AF_INET; - servaddr.sin_addr.s_addr = htonl(INADDR_ANY); - servaddr.sin_port = htons(SERV_PORT); - - if (bind(lfd, (SADDR *)&servaddr, kSize) < 0) { - perror("bind"); - exit(1); - } - - if (listen(lfd, 5) < 0) { - perror("listen"); - exit(1); - } - - while (1) { - unsigned int clilen = kSize; - - if ((cfd = accept(lfd, (SADDR *)&cliaddr, &clilen)) < 0) { - perror("accept"); - exit(1); - } - printf("connection established\n"); - - while ((nread = read(cfd, buf, BUFSIZE)) > 0) { - write(1, &buf, nread); - } - - if (nread == -1) { - perror("read"); - exit(1); - } - close(cfd); - } -} +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#define SADDR struct sockaddr + +int main(int argc, char *argv[]) +{ + + int port = -1; + int bufsize = -1; + while (true) + { + int current_optind = optind ? optind : 1; + + static struct option options[] = {{"bufsize", required_argument, 0, 0}, + {"port", required_argument, 0, 0}, + {0, 0, 0, 0}}; + + int option_index = 0; + int c = getopt_long(argc, argv, "", options, &option_index); + + if (c == -1) + break; + + switch (c) + { + case 0: + { + switch (option_index) + { + case 0: + bufsize = atoi(optarg); + if (bufsize < 0) + { + printf("bufsize should be a positive integer!\n"); + return -1; + } + break; + case 1: + port = atoi(optarg); + if (port < 1 || port > 65535) + { + printf("port should be an integer between 1 and 65535!\n"); + return -1; + } + break; + default: + printf("Index %d is out of options\n", option_index); + } + } + break; + + case '?': + printf("Unknown argument\n"); + break; + default: + fprintf(stderr, "getopt returned character code 0%o?\n", c); + } + } + if (bufsize == -1 || port == -1) + { + fprintf(stderr, "Using: %s --bufsize 100 --port 10050\n", + argv[0]); + return 1; + } + + const size_t kSize = sizeof(struct sockaddr_in); + + int lfd, cfd; + int nread; + char buf[bufsize]; + struct sockaddr_in servaddr; + struct sockaddr_in cliaddr; + + if ((lfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) + { + perror("socket"); + exit(1); + } + + memset(&servaddr, 0, kSize); + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = htonl(INADDR_ANY); + servaddr.sin_port = htons(port); + + if (bind(lfd, (SADDR *)&servaddr, kSize) < 0) + { + perror("bind"); + exit(1); + } + + if (listen(lfd, 5) < 0) + { + perror("listen"); + exit(1); + } + + while (1) + { + unsigned int clilen = kSize; + + if ((cfd = accept(lfd, (SADDR *)&cliaddr, &clilen)) < 0) + { + perror("accept"); + exit(1); + } + printf("connection established\n"); + + while ((nread = read(cfd, buf, bufsize)) > 0) + { + write(1, &buf, nread); + } + + if (nread == -1) + { + perror("read"); + exit(1); + } + close(cfd); + } +} \ No newline at end of file diff --git a/lab7/src/udpclient b/lab7/src/udpclient new file mode 100644 index 000000000..873f015d2 Binary files /dev/null and b/lab7/src/udpclient differ diff --git a/lab7/src/udpclient.c b/lab7/src/udpclient.c old mode 100755 new mode 100644 index 2c02b8d72..d232b432e --- a/lab7/src/udpclient.c +++ b/lab7/src/udpclient.c @@ -1,57 +1,125 @@ -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#define SERV_PORT 20001 -#define BUFSIZE 1024 -#define SADDR struct sockaddr -#define SLEN sizeof(struct sockaddr_in) - -int main(int argc, char **argv) { - int sockfd, n; - char sendline[BUFSIZE], recvline[BUFSIZE + 1]; - struct sockaddr_in servaddr; - struct sockaddr_in cliaddr; - - if (argc != 2) { - printf("usage: client \n"); - exit(1); - } - - memset(&servaddr, 0, sizeof(servaddr)); - servaddr.sin_family = AF_INET; - servaddr.sin_port = htons(SERV_PORT); - - if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) < 0) { - perror("inet_pton problem"); - exit(1); - } - if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { - perror("socket problem"); - exit(1); - } - - write(1, "Enter string\n", 13); - - while ((n = read(0, sendline, BUFSIZE)) > 0) { - if (sendto(sockfd, sendline, n, 0, (SADDR *)&servaddr, SLEN) == -1) { - perror("sendto problem"); - exit(1); - } - - if (recvfrom(sockfd, recvline, BUFSIZE, 0, NULL, NULL) == -1) { - perror("recvfrom problem"); - exit(1); - } - - printf("REPLY FROM SERVER= %s\n", recvline); - } - close(sockfd); -} +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#define SADDR struct sockaddr +#define SLEN sizeof(struct sockaddr_in) + +int main(int argc, char **argv) +{ + + int bufsize = -1; + int port = -1; + char ip[255] = {'\0'}; + + while (true) + { + int current_optind = optind ? optind : 1; + + static struct option options[] = {{"bufsize", required_argument, 0, 0}, + {"ip", required_argument, 0, 0}, + {"port", required_argument, 0, 0}, + {0, 0, 0, 0}}; + + int option_index = 0; + int c = getopt_long(argc, argv, "", options, &option_index); + + if (c == -1) + break; + + switch (c) + { + case 0: + { + switch (option_index) + { + case 0: + bufsize = atoi(optarg); + if (bufsize < 1 || bufsize > 65535) + { + printf("bufsize should be an integer!\n"); + return -1; + } + break; + case 1: + memcpy(ip, optarg, strlen(optarg)); + break; + case 2: + port = atoi(optarg); + if (port < 1 || port > 65535) + { + printf("port should be an integer!\n"); + return -1; + } + break; + default: + printf("Index %d is out of options\n", option_index); + } + } + break; + + case '?': + printf("Unknown argument\n"); + break; + default: + fprintf(stderr, "getopt returned character code 0%o?\n", c); + } + } + + if (bufsize == -1 || port == -1 || strlen(ip) == 0) + { + fprintf(stderr, "Using: %s --bufsize 1024 --ip 0.0.0.0 --port 20001\n", + argv[0]); + return 1; + } + + int sockfd, n; + char sendline[bufsize], recvline[bufsize + 1]; + struct sockaddr_in servaddr; + struct sockaddr_in cliaddr; + + memset(&servaddr, 0, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(port); + + if (inet_pton(AF_INET, ip, &servaddr.sin_addr) < 0) + { + perror("inet_pton problem"); + exit(1); + } + if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) + { + perror("socket problem"); + exit(1); + } + + write(1, "Enter string\n", 13); + + while ((n = read(0, sendline, bufsize)) > 0) + { + if (sendto(sockfd, sendline, n, 0, (SADDR *)&servaddr, SLEN) == -1) + { + perror("sendto problem"); + exit(1); + } + + if (recvfrom(sockfd, recvline, bufsize, 0, NULL, NULL) == -1) + { + perror("recvfrom problem"); + exit(1); + } + + printf("REPLY FROM SERVER= %s\n", recvline); + } + close(sockfd); +} \ No newline at end of file diff --git a/lab7/src/udpserver.c b/lab7/src/udpserver.c old mode 100755 new mode 100644 index 2c7f2dd80..3b1f2a251 --- a/lab7/src/udpserver.c +++ b/lab7/src/udpserver.c @@ -1,56 +1,123 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define SERV_PORT 20001 -#define BUFSIZE 1024 -#define SADDR struct sockaddr -#define SLEN sizeof(struct sockaddr_in) - -int main() { - int sockfd, n; - char mesg[BUFSIZE], ipadr[16]; - struct sockaddr_in servaddr; - struct sockaddr_in cliaddr; - - if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { - perror("socket problem"); - exit(1); - } - - memset(&servaddr, 0, SLEN); - servaddr.sin_family = AF_INET; - servaddr.sin_addr.s_addr = htonl(INADDR_ANY); - servaddr.sin_port = htons(SERV_PORT); - - if (bind(sockfd, (SADDR *)&servaddr, SLEN) < 0) { - perror("bind problem"); - exit(1); - } - printf("SERVER starts...\n"); - - while (1) { - unsigned int len = SLEN; - - if ((n = recvfrom(sockfd, mesg, BUFSIZE, 0, (SADDR *)&cliaddr, &len)) < 0) { - perror("recvfrom"); - exit(1); - } - mesg[n] = 0; - - printf("REQUEST %s FROM %s : %d\n", mesg, - inet_ntop(AF_INET, (void *)&cliaddr.sin_addr.s_addr, ipadr, 16), - ntohs(cliaddr.sin_port)); - - if (sendto(sockfd, mesg, n, 0, (SADDR *)&cliaddr, len) < 0) { - perror("sendto"); - exit(1); - } - } -} +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define SADDR struct sockaddr +#define SLEN sizeof(struct sockaddr_in) + +int main(int argc, char *argv[]) +{ + + int port = -1; + int bufsize = -1; + while (true) + { + int current_optind = optind ? optind : 1; + + static struct option options[] = {{"bufsize", required_argument, 0, 0}, + {"port", required_argument, 0, 0}, + {0, 0, 0, 0}}; + + int option_index = 0; + int c = getopt_long(argc, argv, "", options, &option_index); + + if (c == -1) + break; + + switch (c) + { + case 0: + { + switch (option_index) + { + case 0: + bufsize = atoi(optarg); + if (bufsize < 0) + { + printf("bufsize should be a positive integer!\n"); + return -1; + } + break; + case 1: + port = atoi(optarg); + if (port < 1 || port > 65535) + { + printf("port should be an integer between 1 and 65535!\n"); + return -1; + } + break; + default: + printf("Index %d is out of options\n", option_index); + } + } + break; + + case '?': + printf("Unknown argument\n"); + break; + default: + fprintf(stderr, "getopt returned character code 0%o?\n", c); + } + } + + if (bufsize == -1 || port == -1) + { + fprintf(stderr, "Using: %s --bufsize 1024 --port 20001\n", + argv[0]); + return 1; + } + + int sockfd, n; + char mesg[bufsize], ipadr[16]; + struct sockaddr_in servaddr; + struct sockaddr_in cliaddr; + + if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) + { + perror("socket problem"); + exit(1); + } + + memset(&servaddr, 0, SLEN); + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = htonl(INADDR_ANY); + servaddr.sin_port = htons(port); + + if (bind(sockfd, (SADDR *)&servaddr, SLEN) < 0) + { + perror("bind"); + exit(1); + } + printf("SERVER starts...\n"); + + while (1) + { + unsigned int len = SLEN; + + if ((n = recvfrom(sockfd, mesg, bufsize, 0, (SADDR *)&cliaddr, &len)) < 0) + { + perror("recvfrom"); + exit(1); + } + mesg[n] = 0; + + printf("REQUEST %s FROM %s : %d\n", mesg, + inet_ntop(AF_INET, (void *)&cliaddr.sin_addr.s_addr, ipadr, 16), + ntohs(cliaddr.sin_port)); + + if (sendto(sockfd, mesg, n, 0, (SADDR *)&cliaddr, len) < 0) + { + perror("sendto"); + exit(1); + } + } +} diff --git a/lab7/src/udpsrever b/lab7/src/udpsrever new file mode 100644 index 000000000..7f4c8aea5 Binary files /dev/null and b/lab7/src/udpsrever differ