Разве SO_REUSEADDR о сокете не может хорошо работать в golang? - PullRequest
0 голосов
/ 20 декабря 2018

один IP может поддерживать только порт 65535 для одного пункта назначения.Я надеюсь, что клиент сможет повторно использовать старый tcp_session сразу во время теста производительности, даже если сессия все еще находится в состоянии time_wait.

На моей машине с Linux я открыл эти ключи

sysctl -w net.ipv4.tcp_timestamps=1
sysctl -w net.ipv4.tcp_tw_recycle=1
sysctl -w net.ipv4.tcp_tw_reuse=1

ЗатемЯ пишу следующий код для проверки опции socket_reuse с помощью golang.В коде я привязываю локальный порт 12345.

после первого запуска

$go run 1.go

$netstat -nat | grep 12345
tcp        0      0 192.168.1.11:12345         111.161.3.173:80            TIME_WAIT

после дополнительного запуска

$go run 1.go
Client Connect() called error: cannot assign requested address

Кажется, что SO_REUSEADDR может не работать.Кто-нибудь может помочь решить эту проблему?

package main

import (
    "fmt"
    . "syscall"
)

func main() {
    var (
        clientsock int
        serveraddr SockaddrInet4
        err        error
    )

    if clientsock, err = Socket(AF_INET, SOCK_STREAM, IPPROTO_IP); err != nil {
        fmt.Println("Client Socket() called error:", err.Error())
        return
    }
    SetsockoptInt(clientsock, SOL_SOCKET, SO_REUSEADDR, 1)

    defer Shutdown(clientsock, SHUT_RDWR)

    serveraddr.Addr = [4]byte{111, 161, 3, 173}
    serveraddr.Port = 80

    err = Bind(clientsock, &SockaddrInet4{
        Port: 12345,
    })

    if err = Connect(clientsock, &serveraddr); err != nil {
        fmt.Println("Client Connect() called error:", err.Error())
        return
   }
}

1 Ответ

0 голосов
/ 20 декабря 2018

Вы должны добавить два изменения в свой код:

1) Установить опцию сокета unix.SO_REUSEPORT.

if errReusePort := SetsockoptInt(clientsock, SOL_SOCKET, unix.SO_REUSEPORT, 1); errReusePort != nil {
    fmt.Printf("reuse port error: %v\n", errReusePort)
    return
}

2) Настройте свой код для подключения к различным удаленным конечным точкам TCP.В противном случае, из-за одного источника / порта источника, TCP не сможет различить два идентичных соединения (протокол, src-addr, src-порт, dst-addr, dst-порт).В приведенном ниже примере в командной строке указываются два адреса удаленных серверов.

$ go run main.go 127.0.0.1
connected

$ go run main.go 127.0.0.2
connected

Поиск полного рабочего кода на детской площадке: https://play.golang.org/p/HYLkWlVH6T4

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...