commit 556dbbe54437d8ddd40be6fd754b30414353fde6 Author: stud178869 Date: Wed Oct 1 04:38:38 2025 +0300 Лабораторная работа 3: Сетевые соединения в Python diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..aa6234e --- /dev/null +++ b/.gitignore @@ -0,0 +1,17 @@ +__pycache__/ +*.pyc +*.pyo +.env +network_env/ +.DS_Store +*.log +*.tmp +test_* +venv/ +.env.local +*.env +*.env.local +.vscode/.env +secrets/* +*.key +*.pem diff --git a/README.md b/README.md new file mode 100644 index 0000000..ee8b95d --- /dev/null +++ b/README.md @@ -0,0 +1,14 @@ +# Лабораторная работа 3: Сетевые соединения в Python + +## Цели работы: +- Изучение TCP/UDP протоколов +- Клиент-серверное взаимодействие +- Анализ сетевого трафика в Wireshark +- Работа с HTTP-запросами +- Взаимодействие с API Gitea + +## Содержание: +1. TCP клиент-сервер +2. UDP клиент-сервер +3. HTTP запросы через socket и requests +4. Работа с API Gitea \ No newline at end of file diff --git a/create_issue.py b/create_issue.py new file mode 100644 index 0000000..116217a --- /dev/null +++ b/create_issue.py @@ -0,0 +1,40 @@ +import requests +import os +from dotenv import load_dotenv + +# Загружаем переменные окружения +load_dotenv() +# Получаем токен с правами на запись +TOKEN = os.getenv('GITEA_TOKEN') +if not TOKEN: + print("❌ Ошибка: GITEA_TOKEN не найден в файле .env") + exit() +# Настраиваем заголовки +headers = { + "Authorization": f"token {TOKEN}", + "Content-Type": "application/json" +} +# Данные для создания issue +issue_data = { + "title": "Тестовая задача из лабораторной работы 3", + "body": "Эта задача была создана автоматически через API Gitea в рамках лабораторной работы по сетевым соединениям в Python.\n\n**Выполнено:**\n- TCP/UDP клиент-сервер\n- Анализ трафика в Wireshark\n- HTTP запросы\n- Работа с API" +} +print("🔍 Создаем issue через API Gitea...") +owner = "stud178869" +repo = "test" +# Отправляем запрос на создание issue +response = requests.post( + f"https://git.vyatsu.ru/api/v1/repos/{owner}/{repo}/issues", + headers=headers, + json=issue_data +) +print(f"📊 Статус код: {response.status_code}") +if response.status_code == 201: + issue_info = response.json() + print("✅ Issue успешно создана!") + print(f" Номер: #{issue_info.get('number')}") + print(f" Заголовок: {issue_info.get('title')}") + print(f" URL: {issue_info.get('html_url')}") +else: + print(f"❌ Ошибка при создании issue: {response.status_code}") + print(response.text) \ No newline at end of file diff --git a/gitea_api.py b/gitea_api.py new file mode 100644 index 0000000..81501f0 --- /dev/null +++ b/gitea_api.py @@ -0,0 +1,37 @@ +import requests +import os +from dotenv import load_dotenv + +# Загружаем переменные окружения из файла .env +load_dotenv() + +# Получаем токен из переменных окружения +TOKEN = os.getenv('GITEA_TOKEN') + +if not TOKEN: + print("❌ Ошибка: GITEA_TOKEN не найден в файле .env") + print("Создайте файл .env и добавьте туда: GITEA_TOKEN=ваш_токен") + exit() + +# Настраиваем заголовки для API запроса +headers = {"Authorization": f"token {TOKEN}"} + +print("🔍 Отправляем запрос к API Gitea...") + +# Выполняем запрос к API для получения информации о пользователе +response = requests.get("https://git.vyatsu.ru/api/v1/user", headers=headers) + +print(f"📊 Статус код: {response.status_code}") + +if response.status_code == 200: + user_data = response.json() + print("✅ Запрос выполнен успешно!") + print("\n👤 Информация о пользователе:") + print(f" Логин: {user_data.get('login')}") + print(f" Имя: {user_data.get('full_name', 'Не указано')}") + print(f" Email: {user_data.get('email', 'Не указан')}") + print(f" ID: {user_data.get('id')}") +else: + print(f"❌ Ошибка: {response.status_code}") + print(response.text) + \ No newline at end of file diff --git a/http_requests.py b/http_requests.py new file mode 100644 index 0000000..318786f --- /dev/null +++ b/http_requests.py @@ -0,0 +1,30 @@ +import requests + +def http_via_requests(): + try: + print("Sending HTTP request to vyatsu.ru...") + response = requests.get("http://vyatsu.ru", timeout=10) + + print("Response received!") + print("\n" + "="*50) + print("REQUEST INFO:") + print("="*50) + + print(f"Status code: {response.status_code}") + print(f"URL: {response.url}") + print(f"Response size: {len(response.text)} characters") + + print(f"\nRESPONSE HEADERS:") + for header, value in response.headers.items(): + print(f" {header}: {value}") + + print(f"\nCONTENT (first 500 characters):") + print(response.text[:500]) + if len(response.text) > 500: + print("... (content truncated)") + + except requests.RequestException as e: + print(f"Request error: {e}") + +if __name__ == "__main__": + http_via_requests() \ No newline at end of file diff --git a/http_socket.py b/http_socket.py new file mode 100644 index 0000000..2da087a --- /dev/null +++ b/http_socket.py @@ -0,0 +1,60 @@ +import socket + +def http_via_socket(): + client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + + try: + print("Connecting to vyatsu.ru...") + client.connect(('vyatsu.ru', 80)) + print("Connection established") + + request = ( + "GET / HTTP/1.1\r\n" + "Host: vyatsu.ru\r\n" + "User-Agent: Python-Socket-Client/1.0\r\n" + "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n" + "Accept-Language: ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7\r\n" + "Connection: close\r\n" + "\r\n" + ) + + print("Sending HTTP request...") + client.sendall(request.encode()) + + print("Receiving response...") + response = b"" + while True: + chunk = client.recv(4096) + if not chunk: + break + response += chunk + + decoded_response = response.decode('utf-8', errors='ignore') + + print("\n" + "="*50) + print("SERVER RESPONSE:") + print("="*50) + + headers_end = decoded_response.find('\r\n\r\n') + if headers_end != -1: + headers = decoded_response[:headers_end] + body_start = headers_end + 4 + body_preview = decoded_response[body_start:body_start + 500] + + print("HEADERS:") + print(headers) + print(f"\nBODY (first 500 characters):") + print(body_preview) + if len(decoded_response) > body_start + 500: + print("... (response truncated)") + else: + print(decoded_response[:1000]) + + except Exception as e: + print(f"Error: {e}") + finally: + client.close() + print("\nConnection closed") + +if __name__ == "__main__": + http_via_socket() \ No newline at end of file diff --git a/tcp_client.py b/tcp_client.py new file mode 100644 index 0000000..3192621 --- /dev/null +++ b/tcp_client.py @@ -0,0 +1,32 @@ +import socket + +def run_tcp_client(): + client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + + try: + client.connect(('127.0.0.1', 10000)) + print("Connected to server") + print("Enter messages to send to server") + print("Type 'exit' to quit") + + while True: + message = input("Enter message: ") + client.sendall(message.encode()) + + if message.lower() == 'exit': + break + + data = client.recv(1024) + response = data.decode() + print(f"Server response: {response}") + + except ConnectionRefusedError: + print("Failed to connect to server. Make sure server is running.") + except Exception as e: + print(f"Error: {e}") + finally: + client.close() + print("Connection closed") + +if __name__ == "__main__": + run_tcp_client() \ No newline at end of file diff --git a/tcp_server.py b/tcp_server.py new file mode 100644 index 0000000..e31cde4 --- /dev/null +++ b/tcp_server.py @@ -0,0 +1,41 @@ +import socket + +def run_tcp_server(): + server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + server.bind(("0.0.0.0", 10000)) + server.listen(1) + print("TCP server started on port 10000") + print("Waiting for connections...") + + try: + while True: + conn, addr = server.accept() + print(f"Connection from {addr}") + + with conn: + while True: + data = conn.recv(1024) + if not data: + break + + message = data.decode().strip() + print(f"Received: '{message}'") + + if message.upper() == 'EXIT': + conn.sendall(b"Server shutting down...") + print("Received EXIT command, shutting down") + return + + modified_message = f"ECHO: {message.upper()}" + conn.sendall(modified_message.encode()) + print(f"Sent response: '{modified_message}'") + + except KeyboardInterrupt: + print("\nServer stopped by user") + finally: + server.close() + print("Server socket closed") + +if __name__ == "__main__": + run_tcp_server() \ No newline at end of file diff --git a/udp_client.py b/udp_client.py new file mode 100644 index 0000000..66748fd --- /dev/null +++ b/udp_client.py @@ -0,0 +1,28 @@ +import socket + +def run_udp_client(): + client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + + try: + print("UDP client started") + print("Enter messages to send to server") + print("Type 'exit' to quit") + + while True: + message = input("Enter message: ") + client.sendto(message.encode(), ('127.0.0.1', 10001)) + + if message.lower() == 'exit': + break + + data, _ = client.recvfrom(1024) + print(f"Server response: {data.decode()}") + + except Exception as e: + print(f"Error: {e}") + finally: + client.close() + print("Client closed") + +if __name__ == "__main__": + run_udp_client() \ No newline at end of file diff --git a/udp_server.py b/udp_server.py new file mode 100644 index 0000000..a14506b --- /dev/null +++ b/udp_server.py @@ -0,0 +1,30 @@ +import socket + +def run_udp_server(): + server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + server.bind(('0.0.0.0', 10001)) + print("UDP server started on port 10001") + print("Waiting for messages...") + + try: + while True: + data, addr = server.recvfrom(1024) + message = data.decode().strip() + print(f"Message from {addr}: '{message}'") + + if message.upper() == 'EXIT': + print("Received EXIT command, shutting down") + break + + modified_message = f"UDP-ECHO: {message.upper()} [modified]" + server.sendto(modified_message.encode(), addr) + print(f"Sent response to client: '{modified_message}'") + + except KeyboardInterrupt: + print("\nServer stopped by user") + finally: + server.close() + print("Server socket closed") + +if __name__ == "__main__": + run_udp_server() \ No newline at end of file