Мне нужно проверить, открыты ли на удаленном адресе определенные порты TCP или нет. Я решил использовать golang для этой цели. Вот моя попытка:
func raw_connect(host string, ports []string) {
for _, port := range ports {
timeout := time.Second
conn, err := net.DialTimeout("tcp", host + ":" + port, timeout)
if err != nil {
_, err_msg := err.Error()[0], err.Error()[5:]
fmt.Println(err_msg)
} else {
msg, _, err := bufio.NewReader(conn).ReadLine()
if err != nil {
if err == io.EOF {
fmt.Print(host + " " + port + " - Open!\n")
}
} else {
fmt.Print(host + " " + port + " - " + string(msg))
}
conn.Close()
}
}
}
Это отлично работает для TCP-порта, когда приложение (например, SSH) сначала возвращает строку, я читаю ее и печатаю без промедления.
Однако, когда приложение выше TCP сначала ожидает команды от клиента (например, HTTP), возникает тайм-аут (предложение if err == io.EOF
).
Этот тайм-аут довольно длинный. Мне нужно было бы знать немедленно, если порт открыт или нет.
Есть ли более подходящая техника для этой цели?
Большое спасибо!
Чтобы проверить порт, вы можете проверить, было ли соединение успешным. Например:
func raw_connect(host string, ports []string) {
for _, port := range ports {
timeout := time.Second
conn, err := net.DialTimeout("tcp", net.JoinHostPort(host, port), timeout)
if err != nil {
fmt.Println("Connecting error:", err)
}
if conn != nil {
defer conn.Close()
fmt.Println("Opened", net.JoinHostPort(host, port))
}
}
}
Нет, это невозможно. Это может быть if.else if
или только if.else
. Я думаю, это не имеет значения
Это не работает, по крайней мере, в настоящее время, я просто ставил любые порты, и даже если он закрыт, он все равно говорил, что он открыт. Это просто пинг сервера, я думаю
@Madeo, может быть, у тебя открыты все порты. Это работает для меня.
Проверьте несколько примеров портов
func tcpGather(ip string, ports []string) map[string]string {
// check emqx 1883, 8083 port
results := make(map[string]string)
for _, port := range ports {
address := net.JoinHostPort(ip, port)
// 3 second timeout
conn, err := net.DialTimeout("tcp", address, 3*time.Second)
if err != nil {
results[port] = "failed"
// todo log handler
} else {
if conn != nil {
results[port] = "success"
_ = conn.Close()
} else {
results[port] = "failed"
}
}
}
return results
}
Он также работает для UDP? Я пробовал, но какой бы порт я ни поставил, он всегда говорит мне, что он открыт.
Telnet — это приложение, работающее по протоколу TCP. Соединение UDP невозможно проверить с помощью Telnet.
Возможно ли, что в случае ошибки переменная
conn
все равно будет отличаться отnil
? Просто интересно, почему бы не использовать операторif.else if
.