메인 고루틴 Golang에서 채널을 따라 전송된 마지막 값을 받을 수 없습니다. 채널이 닫히면 고루틴은 다시 새로운 값을 받을 수 없기 때문입니다. 대신 채널의 모든 값이 수신될 때까지 수신 작업을 차단합니다. 이는 수신 작업 중에 발생할 수 있는 교착 상태 상황을 피하기 위해 Golang에서 선택한 디자인입니다. 따라서 잠재적인 문제와 오류를 피하기 위해 Golang 프로그램을 작성할 때 이에 특별한 주의를 기울여야 합니다.
golang에 TCP 포트 스캐너가 제공됩니다. 2가지 구현. 첫 번째는 내 것이고 두 번째는 golang 책에서 가져온 것입니다. 많은 독자들이 이전에 테스트한 것처럼 두 번째 것이 100% 실현 가능하다고 가정합니다. 그러나 둘 다 동일한 문제가 있는 것 같습니다. result 채널에서 전송된 마지막 값을 main 코루틴에서 수신할 수 없으며, 값이 실제로 전송되더라도 채널의 값을 무한정 기다리게 됩니다. 몇 가지 관찰 결과: 포트 수가 21개 미만이면 예상대로 작동하고, 양이 1000을 초과하면 수신되지 않은 양이 약 10으로 증가합니다. 왜 그런지 이해가 안 돼요.
책에서의 구현
func worker(ports, results chan int) { for p := range ports { address := fmt.Sprintf("scanme.nmap.org:%d", p) conn, err := net.Dial("tcp", address) if err != nil { results <- 0 fmt.Println("sent", p) continue } conn.Close() results <- p fmt.Println("sent", p) } } func main() { ports := make(chan int, 100) results := make(chan int) var openports []int for i := 0; i < cap(ports); i++ { go worker(ports, results) } go func() { for i := 1; i <= 50; i++ { ports <- i } }() for i := 0; i < 50; i++ { port := <-results // after 49 it gets stuck infinitely, never proceed further fmt.Println("received", port, i) if port != 0 { openports = append(openports, port) } } close(ports) close(results) sort.Ints(openports) fmt.Println(openports) }
이 문제는 net.Dialer
에 시간 제한을 추가하여 해결되었습니다. 으아악위 내용은 기본 고루틴 Golang에서 채널을 따라 전송된 마지막 값을 받을 수 없습니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!