I am writing a program to check my SOCKS5 proxies. My way is to iterate over each element in the proxy array and create one goroutine for each proxy, and the program was ran perfectly, but, after a while (About 10 seconds after run the program), my program will be stopped for a long time and does nothing, even though it hasn't finished checking the list of proxies. How must I do now? This is my code:
func checkProxy(proxyAddress string, timeout time.Duration, sw *sync.WaitGroup, sm *sync.Mutex) {
retry := 0
headers := []byte("GET / HTTP/1.1\r\nHost: " PROXY_JUDGE_HOST "\r\n\r\n")
for {
if retry == 3 {
break
}
conn, err := SocksClient(proxyAddress, PROXY_JUDGE_ADDRESS, timeout)
if err != nil {
retry
return
}
func(netConn net.Conn) {
defer netConn.Close()
if _, err = conn.Write(headers); err != nil {
return
}
}(conn)
break
}
fmt.Println("Found GOOD proxies: " proxyAddress)
sm.Lock()
liveProxies = append(liveProxies, proxyAddress)
sm.Unlock()
sw.Done()
}
func main() {
var sw sync.WaitGroup
var sm sync.Mutex
totalProxies = readFile("socks5.txt")
for i := 0; i < len(totalProxies); i {
sw.Add(1)
go checkProxy(totalProxies[i], 1*time.Second, &sw, &sm)
}
sw.Wait()
// Code to add proxies list to the new file
}
CodePudding user response:
try this:
- if retry == 3 must return
- if error caught in call
SocksClient
shouldretry
andcontinue
to retry
note : I haven't tried this code bcz I don't have the file
func checkProxy(proxyAddress string, timeout time.Duration, sw *sync.WaitGroup, sm *sync.Mutex) {
defer sw.Done()
retry := 0
headers := []byte("GET / HTTP/1.1\r\nHost: " PROXY_JUDGE_HOST "\r\n\r\n")
for {
if retry == 3 {
return // not break
}
conn, err := SocksClient(proxyAddress, PROXY_JUDGE_ADDRESS, timeout)
if err != nil {
retry
time.Sleep(10*time.Second) // retry in 10 seconds
continue // not return
}
func(netConn net.Conn) {
defer netConn.Close()
if _, err = conn.Write(headers); err != nil {
return
}
}(conn)
break
}
fmt.Println("Found GOOD proxies: " proxyAddress)
sm.Lock()
liveProxies = append(liveProxies, proxyAddress)
sm.Unlock()
}
CodePudding user response:
In your code, there is one path where your function returns before decrementing the counter on the sync.WaitGroup:
func checkProxy(....) {
for {
....
if err != nil {
retry
return
}
}
}
I guess you meant to add a continue
there instead. If there is an error, the sw.Done()
call will never be executed as the function returns before.
As a best practice make sure you defer your sw.Done
call so it is called on any exit path.
func checkProxy(..., sw *sync.WaitGroup, ...) {
defer sw.Done() // decrement once goroutine is done.
}