final
This commit is contained in:
parent
0dd572c17d
commit
1eb9229885
3
.env
3
.env
@ -1 +1,2 @@
|
|||||||
GITEA_TOKEN=95a566ecc1f4d473981658babb9c6b5f2c7b124e
|
GITEA_TOKEN_READ=54f48897b1672651d5f1ef905dd5a7c252330796
|
||||||
|
GITEA_TOKEN_WRITE=3813cb2cc9bd74f9db7884266b6ddffe96aa2e6e
|
||||||
3
.idea/.gitignore
generated
vendored
Normal file
3
.idea/.gitignore
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
6
.idea/inspectionProfiles/profiles_settings.xml
generated
Normal file
6
.idea/inspectionProfiles/profiles_settings.xml
generated
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<component name="InspectionProjectProfileManager">
|
||||||
|
<settings>
|
||||||
|
<option name="USE_PROJECT_PROFILE" value="false" />
|
||||||
|
<version value="1.0" />
|
||||||
|
</settings>
|
||||||
|
</component>
|
||||||
8
.idea/modules.xml
generated
Normal file
8
.idea/modules.xml
generated
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/seti.iml" filepath="$PROJECT_DIR$/.idea/seti.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
8
.idea/seti.iml
generated
Normal file
8
.idea/seti.iml
generated
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="PYTHON_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<content url="file://$MODULE_DIR$" />
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
||||||
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
38
README.md
Normal file
38
README.md
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
# Работа с сетевыми соединениями в Python
|
||||||
|
|
||||||
|
## Описание проекта
|
||||||
|
|
||||||
|
Практическая работа по изучению основ работы с сетевыми соединениями в Python.
|
||||||
|
Реализованы клиент-серверные приложения по протоколам TCP и UDP, выполнен анализ сетевого трафика в Wireshark, проведено сравнение HTTP-запросов через socket и requests, а также выполнено взаимодействие с API Gitea.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Используемые протоколы и методы
|
||||||
|
|
||||||
|
| Протокол/метод | Назначение |
|
||||||
|
|----------------|------------|
|
||||||
|
| **TCP** | Надёжная передача данных с установкой соединения |
|
||||||
|
| **UDP** | Быстрая передача данных без установки соединения |
|
||||||
|
| **HTTP (socket)** | Низкоуровневая отправка HTTP-запросов |
|
||||||
|
| **HTTP (requests)** | Высокоуровневая работа с HTTP-запросами |
|
||||||
|
| **Gitea API** | Взаимодействие с Git-сервером через REST API |
|
||||||
|
| **Wireshark** | Анализ сетевого трафика |
|
||||||
|
|
||||||
|
1. **TCP vs UDP**
|
||||||
|
- TCP надёжный, но медленный. Используется для веб-сайтов, почты, файлов.
|
||||||
|
- UDP быстрый, но может терять данные. Используется для видео, игр, звонков.
|
||||||
|
|
||||||
|
2. **socket vs requests**
|
||||||
|
- `requests` удобнее для реальной разработки: автоматические заголовки, редиректы, меньше кода.
|
||||||
|
- `socket` подходит для низкоуровневого контроля и изучения протокола HTTP.
|
||||||
|
|
||||||
|
3. **Анализ Wireshark**
|
||||||
|
- Зафиксировано трёхстороннее рукопожатие TCP (SYN, SYN-ACK, ACK)
|
||||||
|
- Зафиксирована передача данных с флагом PSH, ACK
|
||||||
|
- Зафиксировано завершение соединения (FIN, ACK)
|
||||||
|
- В UDP подтверждено отсутствие установки соединения
|
||||||
|
|
||||||
|
4. **API Gitea**
|
||||||
|
- Токены должны храниться в `.env` и не попадать в Git
|
||||||
|
- Для чтения нужны права `read:user`
|
||||||
|
- Для создания репозитория нужны права `write:repository`
|
||||||
47
gitea_api.py
47
gitea_api.py
@ -4,18 +4,20 @@ from dotenv import load_dotenv
|
|||||||
|
|
||||||
load_dotenv()
|
load_dotenv()
|
||||||
|
|
||||||
TOKEN = os.getenv("GITEA_TOKEN")
|
TOKEN_READ = os.getenv("GITEA_TOKEN_READ")
|
||||||
|
TOKEN_WRITE = os.getenv("GITEA_TOKEN_WRITE")
|
||||||
|
|
||||||
if not TOKEN:
|
if not TOKEN_READ:
|
||||||
print("Ошибка: токен не найден. Создайте файл .env с GITEA_TOKEN=ваш_токен")
|
print("Ошибка: токен для чтения не найден. Добавьте GITEA_TOKEN_READ в .env")
|
||||||
exit(1)
|
exit(1)
|
||||||
|
|
||||||
headers = {"Authorization": f"token {TOKEN}"}
|
headers_read = {"Authorization": f"token {TOKEN_READ}"}
|
||||||
|
|
||||||
print("=" * 50)
|
print("=" * 50)
|
||||||
print("Проверка подключения к Gitea API")
|
print("Проверка подключения к Gitea API")
|
||||||
print("=" * 50)
|
print("=" * 50)
|
||||||
response = requests.get("https://git.vyatsu.ru/api/v1/user", headers=headers)
|
|
||||||
|
response = requests.get("https://git.vyatsu.ru/api/v1/user", headers=headers_read)
|
||||||
|
|
||||||
if response.status_code == 200:
|
if response.status_code == 200:
|
||||||
user_info = response.json()
|
user_info = response.json()
|
||||||
@ -27,3 +29,38 @@ if response.status_code == 200:
|
|||||||
else:
|
else:
|
||||||
print(f"Ошибка: {response.status_code}")
|
print(f"Ошибка: {response.status_code}")
|
||||||
print(response.text)
|
print(response.text)
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# СОЗДАНИЕ РЕПОЗИТОРИЯ
|
||||||
|
# ============================================
|
||||||
|
|
||||||
|
if not TOKEN_WRITE:
|
||||||
|
print("\n⚠️ Токен для записи не найден. Пропускаем создание репозитория.")
|
||||||
|
exit(0)
|
||||||
|
|
||||||
|
headers_write = {"Authorization": f"token {TOKEN_WRITE}"}
|
||||||
|
|
||||||
|
print("\n" + "=" * 50)
|
||||||
|
print("Создание нового репозитория")
|
||||||
|
print("=" * 50)
|
||||||
|
|
||||||
|
repo_data = {
|
||||||
|
"name": "my-lab3-repo",
|
||||||
|
"description": "Создано через API Gitea",
|
||||||
|
"private": False
|
||||||
|
}
|
||||||
|
|
||||||
|
response = requests.post(
|
||||||
|
"https://git.vyatsu.ru/api/v1/user/repos",
|
||||||
|
headers=headers_write,
|
||||||
|
json=repo_data
|
||||||
|
)
|
||||||
|
|
||||||
|
if response.status_code == 201:
|
||||||
|
print(f"✅ Репозиторий создан: {response.json()['html_url']}")
|
||||||
|
elif response.status_code == 422:
|
||||||
|
print("⚠️ Репозиторий с таким именем уже существует")
|
||||||
|
else:
|
||||||
|
print(f"❌ Ошибка: {response.status_code}")
|
||||||
|
print(response.text)
|
||||||
@ -3,9 +3,19 @@ import socket
|
|||||||
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
client.connect(("vyatsu.ru", 80))
|
client.connect(("vyatsu.ru", 80))
|
||||||
|
|
||||||
request = "GET / HTTP/1.1\r\nHost: vyatsu.ru\r\nConnection: close\r\n\r\n"
|
request = (
|
||||||
|
"GET / HTTP/1.1\r\n"
|
||||||
|
"Host: vyatsu.ru\r\n"
|
||||||
|
"User-Agent: python-requests/2.32.3\r\n"
|
||||||
|
"Accept-Encoding: gzip, deflate\r\n"
|
||||||
|
"Accept: */*\r\n"
|
||||||
|
"Connection: keep-alive\r\n"
|
||||||
|
"\r\n"
|
||||||
|
)
|
||||||
|
|
||||||
client.sendall(request.encode())
|
client.sendall(request.encode())
|
||||||
|
|
||||||
|
# Получаем ответ
|
||||||
response = b""
|
response = b""
|
||||||
while True:
|
while True:
|
||||||
data = client.recv(4096)
|
data = client.recv(4096)
|
||||||
|
|||||||
@ -9,4 +9,8 @@ client.sendall(message.encode())
|
|||||||
data = client.recv(1024)
|
data = client.recv(1024)
|
||||||
print(f"Ответ от сервера: {data.decode()}")
|
print(f"Ответ от сервера: {data.decode()}")
|
||||||
|
|
||||||
|
# Если отправили STOP - сервер завершит работу
|
||||||
|
if message.upper() == "STOP":
|
||||||
|
print("Команда STOP отправлена, сервер завершает работу")
|
||||||
|
|
||||||
client.close()
|
client.close()
|
||||||
@ -3,7 +3,7 @@ import socket
|
|||||||
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
server.bind(("0.0.0.0", 10000))
|
server.bind(("0.0.0.0", 10000))
|
||||||
server.listen(1)
|
server.listen(1)
|
||||||
print("TCP сервер запущен на порту 10000")
|
print("TCP сервер запущен")
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
conn, addr = server.accept()
|
conn, addr = server.accept()
|
||||||
@ -13,14 +13,12 @@ while True:
|
|||||||
if not data:
|
if not data:
|
||||||
break
|
break
|
||||||
|
|
||||||
response = data.upper()
|
conn.sendall(data.upper())
|
||||||
conn.sendall(response)
|
|
||||||
print(f"Отправлено: {response}")
|
|
||||||
|
|
||||||
conn.close()
|
conn.close()
|
||||||
|
|
||||||
if response == b'EXIT':
|
if data.upper() == b'STOP':
|
||||||
print("Завершение сервера")
|
print("Получена команда STOP, сервер завершает работу")
|
||||||
break
|
break
|
||||||
|
|
||||||
server.close()
|
server.close()
|
||||||
|
print("Сервер остановлен")
|
||||||
Loading…
Reference in New Issue
Block a user