Форум программистов, компьютерный форум, киберфорум
Python: Сети
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.60/5: Рейтинг темы: голосов - 5, средняя оценка - 4.60
0 / 0 / 0
Регистрация: 23.03.2021
Сообщений: 61

Сетевой чат TCP/UDP

09.06.2023, 08:57. Показов 1458. Ответов 5

Студворк — интернет-сервис помощи студентам
Помогите исправить ошибку.
Создан сетевой чат, который позволяет выбирать отправку сообщений, используя транспортную подсистему протоколов TCP или UDP.
Проблема в том что с UDP он не работает и выдает ошибку (с TCP все отлично)
код сервера
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
import socket
import threading
 
# Определяем хост и порт для соединения
HOST = 'localhost'
PORT = 5555
 
# Создаем сокет
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 
# Связываем сокет с хостом и портом
server.bind((HOST, PORT))
 
# Слушаем входящие соединения
server.listen()
 
# Список клиентов и их идентификаторов
clients = {}
client_ids = 0
 
# Функция для обработки входящих сообщений от клиентов
def handle_client(client_socket, client_address):
    global clients, client_ids
 
    # Присваиваем идентификатор клиенту
    client_id = client_ids
    client_ids += 1
 
    # Добавляем клиента в список
    clients[client_id] = client_socket
 
    # Отправляем клиенту его идентификатор
    client_socket.send(str(client_id).encode())
 
    # Принимаем сообщения от клиента и пересылаем их другим клиентам
    while True:
        try:
            message = client_socket.recv(1024)
            if message:
                message_str = message.decode()
                print(f"Received message from {client_id}: {message_str}")
 
                # Отправляем сообщение всем клиентам, кроме отправителя
                for id, socket in clients.items():
                    if id != client_id:
                        socket.send(message)
            else:
                # Если клиент отключился, удаляем его из списка
                client_socket.close()
                del clients[client_id]
                print(f"Client {client_id} disconnected")
                break
        except:
            # Если произошла ошибка, удаляем клиента из списка
            client_socket.close()
            del clients[client_id]
            print(f"Client {client_id} disconnected")
            break
 
 
# Функция для запуска сервера
def start_server():
    print(f"Server started on {HOST}:{PORT}")
    while True:
        # Принимаем входящие соединения и запускаем новый поток для обработки каждого клиента
        client_socket, client_address = server.accept()
        print(f"New client connected: {client_address}")
 
        client_thread = threading.Thread(target=handle_client, args=(client_socket, client_address))
        client_thread.start()
 
 
if __name__ == '__main__':
    start_server()
--------------------------------------------------------------------------
Код клиента
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import socket
import threading
 
# Определяем хост и порт для соединения  
HOST = 'localhost'
PORT = 5555
 
# Выбираем протокол (TCP или UDP)
protocol = input("Choose protocol (TCP/UDP): ").lower()
 
# Создаем сокет
if protocol == "tcp":
    client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
elif protocol == "udp":
    client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
else:
    print("Invalid protocol")
    exit()
 
# Функция для отправки сообщений
def send_message():
    while True:
        message = input()
        # Добавляем к сообщению идентификатор клиента
        message_with_id = f"{client_id}: {message}"
        if protocol == "tcp":
            client_socket.send(message_with_id.encode())
        elif protocol == "udp":
            client_socket.sendto(message_with_id.encode(), (HOST, PORT))
 
# Функция для приема сообщений
def receive_message():
    while True:
        if protocol == "tcp":
            message = client_socket.recv(1024).decode()
        elif protocol == "udp":
            data, address = client_socket.recvfrom(1024)
            if data:
                message = data.decode()
            else:
                continue
        print(message)
 
# Подключаемся к серверу
if protocol == "tcp":
    client_socket.connect((HOST, PORT))
    # Получаем идентификатор клиента от сервера
    client_id = int(client_socket.recv(1024).decode())
    print(f"You are client {client_id}")
elif protocol == "udp":
    # Отправляем пустое сообщение, чтобы получить идентификатор клиента от сервера
    client_socket.sendto(b"", (HOST, PORT))
    data, address = client_socket.recvfrom(1024)
    if data:
        client_id = int(data.decode())
        print(f"You are client {client_id}")
    else:
        print("Error getting client ID from server")
        exit()
 
 
# Запускаем потоки для отправки и приема сообщений
send_thread = threading.Thread(target=send_message)
send_thread.start()
 
receive_thread = threading.Thread(target=receive_message)
receive_thread.start()
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
09.06.2023, 08:57
Ответы с готовыми решениями:

UDP и TCP сервер
Здравствуйте. К сети подключено несколько датчиков, которые периодически отправляют UDP пакеты на основной сервер. Сервер сохраняет...

Как реализовать чат между клиентом и сервером, используя UDP и ООП
Добрый день, я новичок в изучении пайтона, пытаюсь реализовать клиент серверный обмен сообщениями по протоколу udp, проще говоря чат. ...

Сетевой чат UDP
Пишу чат UDP, в процессе возникла ошибка, с которой не могу справиться. int main() { int sock; struct sockaddr_in...

5
Автоматизируй это!
Эксперт Python
 Аватар для Welemir1
7392 / 4819 / 1246
Регистрация: 30.03.2015
Сообщений: 13,694
Записей в блоге: 29
09.06.2023, 09:24
qwdcew, то есть для клиента ты меняешь настройки в зависимости от выбора, а для сервера просто оставляешь тсп и ждешь что датаграм на нем тоже сработает? разверни 2 сокета на разных портах -1 для тсп и 1 удп, а клиент пусть подключается к нужному.
0
0 / 0 / 0
Регистрация: 23.03.2021
Сообщений: 61
09.06.2023, 10:26  [ТС]
Welemir1, что то на подобии этого?)
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
import socket
import threading
 
# Определяем хост и порты для соединения
HOST = 'localhost'
TCP_PORT = 5555
UDP_PORT = 3334
 
# Создаем сокеты
tcp_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
udp_server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
 
# Связываем сокеты с хостом и портами
tcp_server.bind((HOST, TCP_PORT))
udp_server.bind((HOST, UDP_PORT))
 
# Слушаем входящие соединения
tcp_server.listen()
 
# Список клиентов и их идентификаторов для TCP сокета
tcp_clients = {}
tcp_client_ids = 0
 
# Функция для обработки входящих сообщений от TCP клиентов
def handle_tcp_client(client_socket, client_address):
    global tcp_clients, tcp_client_ids
 
    # Присваиваем идентификатор клиенту
    client_id = tcp_client_ids
    tcp_client_ids += 1
 
    # Добавляем клиента в список
    tcp_clients[client_id] = client_socket
 
    # Отправляем клиенту его идентификатор
    client_socket.send(str(client_id).encode())
 
    # Принимаем сообщения от клиента и пересылаем их другим клиентам
    while True:
        try:
            message = client_socket.recv(1024)
            if message:
                message_str = message.decode()
                print(f"Received message from {client_id}: {message_str}")
 
                # Отправляем сообщение всем клиентам, кроме отправителя
                for id, socket in tcp_clients.items():
                    if id != client_id:
                        socket.send(message)
            else:
                # Если клиент отключился, удаляем его из списка
                client_socket.close()
                del tcp_clients[client_id]
                print(f"TCP client {client_id} disconnected")
                break
        except:
            # Если произошла ошибка, удаляем клиента из списка
            client_socket.close()
            del tcp_clients[client_id]
            print(f"TCP client {client_id} disconnected")
            break
 
# Функция для обработки входящих сообщений от UDP клиентов
def handle_udp_client():
    while True:
        data, address = udp_server.recvfrom(1024)
        if data:
            message = data.decode()
            print(f"Received message from {address}: {message}")
 
            # Отправляем сообщение всем клиентам, включая отправителя
            for id, socket in tcp_clients.items():
                socket.send(message.encode())
 
# Функция для запуска сервера
def start_server():
    print(f"Server started on {HOST}:{TCP_PORT} (TCP) and {HOST}:{UDP_PORT} (UDP)")
    # Запускаем поток для обработки входящих сообщений от UDP клиентов
    udp_thread = threading.Thread(target=handle_udp_client)
    udp_thread.start()
 
    while True:
        # Принимаем входящие соединения и запускаем новый поток для обработки каждого TCP клиента
        tcp_client_socket, tcp_client_address = tcp_server.accept()
        print(f"New TCP client connected: {tcp_client_address}")
 
        tcp_client_thread = threading.Thread(target=handle_tcp_client, args=(tcp_client_socket, tcp_client_address))
        tcp_client_thread.start()
 
if __name__ == '__main__':
    start_server()

клиент
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import socket
import threading
 
# Определяем хост и порты для соединения  
HOST = 'localhost'
TCP_PORT =5555
UDP_PORT = 3334
 
# Выбираем протокол (TCP или UDP)
protocol = input("Choose protocol (TCP/UDP): ").lower()
 
# Создаем сокет
if protocol == "tcp":
    client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    port = TCP_PORT
elif protocol == "udp":
    client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    port = UDP_PORT
else:
    print("Invalid protocol")
    exit()
 
# Функция для отправки сообщений
def send_message():
    while True:
        message = input()
        # Добавляем к сообщению идентификатор клиента
        message_with_id = f"{client_id}: {message}"
        if protocol == "tcp":
            client_socket.send(message_with_id.encode())
        elif protocol == "udp":
            client_socket.sendto(message_with_id.encode(), (HOST, port))
 
# Функция для приема сообщений
def receive_message():
    while True:
        if protocol == "tcp":
            message = client_socket.recv(1024).decode()
        elif protocol == "udp":
            data, address = client_socket.recvfrom(1024)
            if data:
                message = data.decode()
            else:
                continue
        print(message)
 
# Подключаемся к серверу
if protocol == "tcp":
    client_socket.connect((HOST, port))
    # Получаем идентификатор клиента от сервера
    client_id = int(client_socket.recv(1024).decode())
    print(f"You are client {client_id}")
elif protocol == "udp":
    # Отправляем пустое сообщение, чтобы получить идентификатор клиента от сервера
    client_socket.sendto(b"", (HOST, port))
    data, address = client_socket.recvfrom(1024)
    if data:
        client_id = int(data.decode())
        print(f"You are client {client_id}")
    else:
        print("Error getting client ID from server")
        exit()
 
# Запускаем потоки для отправки и приема сообщений
send_thread = threading.Thread(target=send_message)
send_thread.start()
 
receive_thread = threading.Thread(target=receive_message)
receive_thread.start()
0
Автоматизируй это!
Эксперт Python
 Аватар для Welemir1
7392 / 4819 / 1246
Регистрация: 30.03.2015
Сообщений: 13,694
Записей в блоге: 29
09.06.2023, 10:40
qwdcew, если работает то да. Осталось кучи ифов заменить классами, первый умеет все для тсп а второй для удп, при выборе создавать объект и с ним работать.
0
0 / 0 / 0
Регистрация: 23.03.2021
Сообщений: 61
09.06.2023, 11:16  [ТС]
Welemir1, но UDP по прежнему не работает)
0
Автоматизируй это!
Эксперт Python
 Аватар для Welemir1
7392 / 4819 / 1246
Регистрация: 30.03.2015
Сообщений: 13,694
Записей в блоге: 29
09.06.2023, 15:43
qwdcew, не говори ни слова больше, дай мне самому угадать что ты делаешь, какие ошибки падают...
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
09.06.2023, 15:43
Помогаю со студенческими работами здесь

Примитивный TCP-UDP чат на winsocket
СРОЧНО нужна помощь, вопрос жизни и работы. Сваял по примерам такой чат, но сокет блокируемый, то-бишь я не могу прислать несколько...

TCP/IP пакеты. Как можно изменить служебные параметры заголовка TCP или UDP?
Всем привет! Работаю с передачей данных через интернет. Как можно изменить служебные параметры заголовка TCP или UDP (флаги, контрольная...

UDP чат
Здравствуйте, с C++ знаком около недели, но нужно сделать сетевой чат по UDP. По разным мануалам сделал вот что. Код сервера. //...

UDP чат
ok ok ПривеТ! ВСЕМ я тут извелся на днях!!! КАК Сделат простенький UDP чАт на C++ Builder 6 !! PLZ! пацаны напешите код ести не...

Чат на C# с UDP
Доброго времени! Вобщем пишу для личных целей простенький чат, который состооит из сервара и клиента. Ошибка в них одна и та самая: цикл...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Новые блоги и статьи
1С: Программный отбор элементов справочника Номенклатура по группе
Maks 22.03.2026
Установка программного отбора элементов справочника "Номенклатура" из модуля формы документа. В качестве фильтра для отбора справочника служит группа номенклатуры. Отбор под наименованию группы (на. . .
Как я обхитрил таблицу Word
Alexander-7 21.03.2026
Когда мигает курсор у внешнего края таблицы, и нам надо перейти на новую строку, а при нажатии Enter создается новый ряд таблицы с ячейками, то мы вместо нервных нажатий Энтеров мы пишем любые буквы. . .
Krabik - рыболовный бот для WoW 3.3.5a
AmbA 21.03.2026
без регистрации и смс. Это не торговля, приложение не содержит рекламы. Выполняет свою непосредственную задачу - автоматизацию рыбалки в WoW - и ничего более. Однако если админы будут против -. . .
1С: Программный отбор элементов справочника Сотрудники по значению перечисления
Maks 21.03.2026
Установка программного отбора элементов справочника "Сотрудники" из модуля формы документа. В качестве фильтра для отбора служит предопределенное значение перечислений. Процедура. . .
Переходник USB-CAN-GPIO
Eddy_Em 20.03.2026
Достаточно давно на работе возникла необходимость в переходнике CAN-USB с гальваноразвязкой, оный и был разработан. Однако, все меня терзала совесть, что аж 48-ногий МК используется так тупо: просто. . .
Оттенки серого
Argus19 18.03.2026
Оттенки серого Нашёл в интернете 3 прекрасных модуля: Модуль класса открытия диалога открытия/ сохранения файла на Win32 API; Модуль класса быстрого перекодирования цветного изображения в оттенки. . .
SDL3 для Desktop (MinGW): Рисуем цветные прямоугольники с помощью рисовальщика SDL3 на Си и C++
8Observer8 17.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-rectangles-sdl3-c. zip finish-rectangles-sdl3-cpp. zip
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие. Ссылка в Linux — это запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая ссылка» (hard link),. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru