Сервер пользователь сортировка матрицы
У меня есть два файла, это сервер и пользователь. Вопрос такой. Программа работает с матрицей 1000 на 1000 и сортирует ее слиянием, деревом, хэш таблицей. Если я запущу на своем компьютере программу сервера и клиента мой пакет TCP будет 35000 байт в Wireshark, а если на разных то 35000 байт нету, а все 45, почему? С буфером или со стеком что то, или еще что, скажите пожалуйста.
Сервер
import socket
import random
class SortingServer:
def __init__(self, host, port):
# Инициализация сервера сокетов по указанному хосту и порту
self.host = host # Присваивание хоста, к которому происходит привязка
self.port = port # Присваивание порта, который используется для подключения
# Создание серверного сокета с помощью модуля socket
# socket.AF_INET указывает, что мы используем протокол IPv4
# socket.SOCK_STREAM указывает, что мы работаем с TCP-сокетом
self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server.bind((self.host, self.port)) # Привязка серверного сокета к заданному хосту и порту
# Начало прослушивания подключений к серверному сокету
# Ожидается только одно соединение
self.server.listen(1)
self.client, self.address = self.server.accept() # Принятие подключения от клиента
print(f"Подключено к {self.address}")
# Генерируем матрицу
def generate_and_save_matrix(self, rows, cols, file_path):
matrix = [[random.randint(0, 9) for _ in range(cols)] for _ in range(rows)]
with open(file_path, 'w') as file:
for row in matrix:
row_str = ' '.join(f"{num: <2}" for num in row) # Форматированный вывод с фиксированной шириной
file.write(row_str + '\n')
return matrix
# Отправляем матрицу
def send_matrix(self, matrix):
matrix_str = '\n'.join([' '.join(map(str, row)) for row in matrix])
self.client.send(matrix_str.encode())
def merge_sort(self, matrix):
# Реализация сортировки слиянием для матрицы
sorted_matrix = []
for row in matrix:
sorted_row = sorted(row)
sorted_matrix.append(sorted_row)
return sorted_matrix
# def merge_sort(self, matrix):
# def merge(left, right):
# # Реализация сортировки слиянием для матрицы
# result = []
# i = j = 0
# while i < len(left) and j < len(right):
# if left[i] < right[j]:
# result.append(left[i])
# i += 1
# else:
# result.append(right[j])
# j += 1
# result.extend(left[i:])
# result.extend(right[j:])
# return result
# def merge_sort_recursive(arr):
# if len(arr) <= 1:
# return arr
# mid = len(arr) // 2
# left = merge_sort_recursive(arr[:mid])
# right = merge_sort_recursive(arr[mid:])
# return merge(left, right)
# sorted_matrix = [merge_sort_recursive(row) for row in matrix]
# return sorted_matrix
def heap_sort(self, matrix):
# Реализация пирамидальной сортировки для матрицы
def heapify(arr, n, i):
largest = i
left = 2 * i + 1
right = 2 * i + 2
if left < n and arr[i] < arr[left]:
largest = left
if right < n and arr[largest] < arr[right]:
largest = right
if largest != i:
arr[i], arr[largest] = arr[largest], arr[i]
heapify(arr, n, largest)
def build_heap(arr):
n = len(arr)
for i in range(n // 2 - 1, -1, -1):
heapify(arr, n, i)
sorted_matrix = []
# Применение пирамидальной сортировки к каждой строке матрицы
for row in matrix:
build_heap(row)
sorted_row = []
for i in range(len(row) - 1, -1, -1):
row[0], row[i] = row[i], row[0]
heapify(row, i, 0)
sorted_row.insert(0, row.pop(0))
sorted_matrix.append(sorted_row)
return sorted_matrix
def tree_sort(self, matrix):
# Реализация сортировки деревом для матрицы
def insert(root, key):
if root is None:
return {'key': key, 'left': None, 'right': None}
if key < root['key']:
root['left'] = insert(root['left'], key)
else:
root['right'] = insert(root['right'], key)
return root
def in_order_traversal(root, sorted_arr):
# Рекурсивная функция обхода дерева в порядке "влево - корень - вправо"
# # Проверяем, существует ли текущий узел (если не пуст)
if root:
in_order_traversal(root['left'], sorted_arr) # # Рекурсивно обходим левое поддерево
sorted_arr.append(root['key']) # # Добавляем значение текущего узла в список
in_order_traversal(root['right'], sorted_arr) # # Рекурсивно обходим правое поддерево
sorted_matrix = [] # Создание списка для хранения отсортированных строк
# Итерация по каждой строке в матрице
for row in matrix:
root = None # Инициализация переменной для хранения дерева текущей строки
# Добавление каждого элемента строки в дерево
for num in row:
root = insert(root, num)
sorted_row = [] # Создание списка для отсортированных значений текущей строки
in_order_traversal(root, sorted_row) # Обход дерева в порядке "влево - корень - вправо" и добавление значений в список
sorted_matrix.append(sorted_row) # Добавление отсортированной строки в список отсортированных строк матрицы
return sorted_matrix
def binary_search(self, matrix, target):
# Реализация бинарного поиска в матрице
def binary_search_row(arr, target):
low = 0
high = len(arr) - 1
while low <= high:
mid = (low + high) // 2
if arr[mid] == target:
return True
elif arr[mid] < target:
low = mid + 1
else:
high = mid - 1
return False
for row in matrix:
if binary_search_row(row, target):
return True
return False
def hash_table_search(self, matrix, target):
# Реализация поиска с использованием хэш-таблицы
hash_table = {}
for row_index, row in enumerate(matrix):
for col_index, val in enumerate(row):
if val not in hash_table:
hash_table[val] = []
hash_table[val].append((row_index, col_index))
if target in hash_table:
return True, hash_table[target]
return False, []
# Обработка запросов клиента
def handle_client(self):
while True:
choice = self.client.recv(1024).decode()
if not choice:
break
# Обработка выбора пользователя
if choice == '1':
matrix = self.generate_and_save_matrix(1000, 1000, 'matrix.txt') # Создание и сохранение матрицы
self.send_matrix(matrix)
elif choice == '2':
# Получение выбора сортировки от клиента и применение соответствующего метода сортировки
sort_choice = self.client.recv(1024).decode()
if sort_choice == '1':
sorted_matrix = self.merge_sort(matrix)
elif sort_choice == '2':
sorted_matrix = self.heap_sort(matrix)
elif sort_choice == '3':
# Получение выбора поиска от клиента и выполнение соответствующего поиска
sorted_matrix = self.tree_sort(matrix)
self.send_matrix(sorted_matrix)
elif choice == '3':
search_choice = self.client.recv(1024).decode()
target = int(self.client.recv(1024).decode())
if search_choice == '1':
found = self.binary_search(matrix, target)
self.client.send(str(found).encode())
elif search_choice == '2':
found, positions = self.hash_table_search(matrix, target)
self.client.send(str(found).encode())
if found:
positions_str = ', '.join([f"({pos[0]}, {pos[1]})" for pos in positions])
self.client.send(positions_str.encode())
# Закрытие сервера
def close(self):
self.server.close()
# ip.addr== 192.168.0.123 and tcp
if __name__ == "__main__":
host = '192.168.0.123' # Указание IP-адреса хоста
port = 12345 # Указание порта для подключения
server = SortingServer(host, port) # Создание сервера с указанными параметрами
server.handle_client() # Обработка запросов клиента
server.close() # Закрытие сервера
# 1) Фрагментация данных: Если передаваемые данные слишком большие, они могут быть разделены на фрагменты для передачи по сети. Это может привести к разным размерам пакетов.
# 2) Буферизация: Размеры пакетов могут зависеть от того, как данные обрабатываются в буферах. Например, если данные отправляются блоками, размеры могут различаться.
# 3) Протокол TCP: TCP может управлять потоком данных и разбивать их на сегменты, чтобы обеспечить эффективную передачу. Это может вызвать изменение размера пакетов.
# 4) Работа сокетов: Настройки сокетов, такие как размер буфера, также могут влиять на размер передаваемых пакетов.
Клиент
import socket
class SortingClient:
def __init__(self, host, port):
# Инициализация клиента сокетов с указанным хостом и портом
self.host = host
self.port = port
self.client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.client.connect((self.host, self.port))
# Отображение меню выбора действий для пользователя
def display_menu(self):
print("1. Сгенерировать матрицу")
print("2. Отсортировать матрицу")
print("3. Поиск в матрице")
choice = input("Введите ваш выбор: ")
return choice
# Отображение методов сортировки для выбора пользователя
def display_sorting_methods(self):
print("Выберите метод сортировки:")
print("1. Сортировка слиянием")
print("2. Пирамидальная сортировка")
print("3. Сортировка деревом")
method = input("Введите выбранный метод сортировки: ")
return method
# Отображение методов поиска для выбора пользователя
def display_search_methods(self):
print("Выберите метод поиска:")
print("1. Бинарный поиск")
print("2. Поиск с использованием хэш-таблицы")
method = input("Введите выбранный метод поиска: ")
return method
# Получение данных матрицы от сервера
def receive_matrix(self):
matrix_data = self.client.recv(4096).decode()
rows = matrix_data.split('\n')
sorted_matrix = []
with open('savematrix.txt', 'w') as file:
for row in rows:
formatted_row = row.split()
row_str = ' '.join(f"{num: <2}" for num in formatted_row)
sorted_matrix.append(row_str)
file.write(row_str + '\n')
for row_str in sorted_matrix:
print(row_str)
# Отправка выбора действия на сервер
def send_choice(self, choice):
# через сокет
self.client.send(choice.encode())
# Отправка выбранного метода сортировки на сервер
def send_sorting_method(self, method):
# через сокет
self.client.send(method.encode())
# Отправка целевого значения для поиска на сервер
def send_target(self, target):
# через сокет
self.client.send(target.encode())
# Получение результата от сервера
def receive_result(self):
# через сокет и его отображение
result = self.client.recv(4096).decode()
print(result)
# Закрытие соединения клиента
def close(self):
self.client.close()
if __name__ == "__main__":
host = '192.168.0.123' # IP-адрес сервера
port = 12345 # Порт сервера
client = SortingClient(host, port) # Создание клиента с указанными параметрами
while True:
choice = client.display_menu() # Отображение меню и получение выбора пользователя
client.send_choice(choice) # Отправка выбранного действия на сервер
if choice == '1':
client.receive_matrix() # Получение сгенерированной матрицы от сервера
elif choice == '2':
sorting_method = client.display_sorting_methods() # Отображение методов сортировки
client.send_sorting_method(sorting_method) # Отправка выбранного метода сортировки на сервер
client.receive_matrix() # Получение отсортированной матрицы
elif choice == '3':
search_method = client.display_search_methods() # Отображение методов поиска
client.send_choice(search_method) # Отправка выбранного метода поиска на сервер
target = input("Введите целевое значение для поиска: ")
client.send_target(target) # Отправка целевого значения для поиска на сервер
client.receive_result() # Получение результата поиска
client.close() # Закрытие соединения с сервером