Как общаться с несколькими клиентами на сервере UDP в go? - PullRequest
0 голосов
/ 01 апреля 2020

У меня есть сервер, который передает файлы по UDP, и он работает хорошо, когда одновременно работает только один клиент, но если другой клиент пытается подключиться, выдается следующая ошибка

listen udp: 20000: bind: обычно разрешено только одно использование каждого адреса сокета (протокола / сетевого адреса / порта).

Это мой код в основном:

...
fmt.Println("Input the number of connections")
var number int
fmt.Scanln(&number)

var wg sync.WaitGroup
wg.Add(number)

lAdd, err := net.ResolveUDPAddr("udp", PORT)
if err != nil {
    fmt.Println(err)
    return
}

for i:=0; i < number; i++ {
    go startConnection(lAdd, file, i, wg)
}
wg.Wait()

Это код startConnection:

func startConnection (lAdd * net.UDPAddr, archivo string, i int, wg sync.WaitGroup) {

defer wg.Done()

conn, err := net.ListenUDP("udp", lAdd)
if err != nil {
    logger.Println("There was an error: ", err)
    return
}

defer conn.Close()

sendFile (conn, add, archivo, i)
}

1 Ответ

0 голосов
/ 02 апреля 2020

Сервер должен вызвать Listen только один раз, чтобы запустить прослушиватель. В этот момент он слушает. Именно здесь TCP и UDP расходятся из-за природы протоколов.

ListenTCP возвращает TCPListener, который можно использовать для Accept подключений при их входе. Каждое подключение может затем отправлять и получать данные.

ListenUDP возвращает UDPConn, то же самое, что и DialUDP, поскольку UDP является протоколом без установления соединения. Вы просто читаете и пишете в UDPConn. Заголовки пакетов UDP включают информацию об источнике и цели, поэтому вы можете использовать ReadFrom для чтения данных и просмотра того, кто их отправил, и WriteTo для ответа на указанный c клиент.

В этой статье есть довольно подробное изложение реализации UDP-соединения в Go: https://ops.tips/blog/udp-client-and-server-in-go/

...