Когда будет достаточно одного сокета, когда мне нужно создать больше? - PullRequest
2 голосов
/ 09 августа 2010

Аспект UDP без установления соединения привел меня к циклу ...

Если я установлю для UDP-сокета значение INADDR_ANY, а затем свяжу его с портом 33445 на локальной машине, машина приметвходящие соединения от разных клиентов.Все эти соединения будут обслуживаться этим одним сокетом, поскольку это не TCP, и я не могу порождать новые дочерние сокеты для непосредственной обработки каждого соединения.Я могу ответить любому, нескольким или всем этим подключенным клиентам из их последнего сообщения.

Так что, где все становится немного неясным для меня, здесь ...

Могу ли яВы также можете отправлять сообщения в любое время любому из этих клиентов?или я могу только отправлять сообщения, которые в ответ на recvfrom ()?

Отдельно, если я хотел, чтобы этот сервер (пока он обслуживал клиентов) подключался к другому серверу и имел разговор о чем-то другом, я полагаюнужно будет создать новый сокет для этой цели?Я не могу просто использовать существующий сокет сервера и указать новый адрес назначения?

Большое спасибо этому замечательному сообществу.

Редактировать: Позвольте мне выразить это по-другому.может использовать только связанный сокет для ответа клиентам, которые ранее достигли меня в этом сокете.Чтобы инициировать разговор с новым хостом, я не могу просто использовать связанный сокет для этой цели?Я должен создать новый сокет для доступа к серверу, который прослушивает, правильно?

Ответы [ 2 ]

3 голосов
/ 09 августа 2010

UDP-сокеты могут работать в двух разных режимах:

  • по умолчанию режим без подключения : все дейтаграммы, отправленные на порт / адрес вашего процесса, получены; вам нужно указывать адрес назначения для каждого отправляемого вами сообщения.
  • подключен : принимаются только дейтаграммы, отправленные с адреса / порта, к которому вы подключены; вам не нужно указывать адрес назначения при каждом отправлении.

Вот небольшой обзор подключенных UDP-сокетов .

Edit:

Вот небольшой Python UDP-сервер, который принимает пакеты от любого клиента и копирует их на второй сервер. Все сделано с одним неподключенным сокетом UDP.

#!/usr/bin/env python
import sys, socket, string

if len( sys.argv ) != 4:
        print "Usage: udptee <local-listen-port> <copy-host> <copy-port>"
        exit( 1 )

copy = ( sys.argv[2], int( sys.argv[3] ))

s = socket.socket( socket.AF_INET, socket.SOCK_DGRAM )
#s.bind(( 'localhost', int( sys.argv[1] )))
s.bind(( '', int( sys.argv[1] )))

print "listening on ", s.getsockname()
print "copying to", copy

while True:
        line, addr = s.recvfrom( 1024 )
        print "received: ", line, " from ", addr
        s.sendto( line, addr ) # echo to source
        s.sendto( line, copy ) # copy to tee
        if string.strip( line ) == "exit": break

print "Goodbye and thanks for all the fish"
s.close()

Запустите его в одном терминале как:

~$ ./udptee 9090 <IP-of-copy-server> 9999

Затем запустите netcat в режиме сервера во втором семестре. Этот примет копии дейтаграмм:

# this used to be "nc -ul 127.0.0.1 9999" which only listened on loopback
~$ nc -ul 9999

Запустить netcat клиента в третий срок, чтобы отправить материал на первый сервер:

~$ nc -u <IP-of-tee-server> 9090

Начните печатать и увидите, что оба сервера отражают то, что вы печатаете.

1 голос
/ 09 августа 2010

UDP-сокеты не подключены к удаленному хосту или клиенту, поэтому все, что вам нужно сделать, это использовать sendto (), используя адрес назначения и UDP-сокет, который вы инициализировали. Так что да, вы можете отправлять сообщения с использованием сокета UDP в любое время, если вы правильно настроили сокет UDP. Просто установите адрес получения в структуре sockaddr, которую вы используете. Если принимающей части привязан UDP-сокет к порту, с которого вы отправляете сообщение, он получит его.

От этого второго вопроса все зависит, использует ли разговор с этим вторым сервером другой порт. Если он использует тот же порт, то нет необходимости создавать еще один сокет UDP. Вам просто нужно как-то отделить сообщения, которые сервер 1 получает от своих клиентов, от сообщений, которые он получает от сервера 2.

Я бы рекомендовал взглянуть на превосходное руководство Биджа, главы 5.8 и 6.3.

Руководство Биджа по сетевому программированию

...