Answer the question
In order to leave comments, you need to log in
How to correctly close a tcp connection?
There is a service written in Go running on Ubuntu 16.04.
The essence of the work is that it polls about 30 servers.
After receiving data from the server, it must in response send information that the data has been received, in response to this, the server will throw another portion of data, and so on. It happens that the data on the server is over, and then I just fall asleep for 60 seconds, then everything is new.
It also happens that the servers do not respond (a network break or some other problem on the server side (it doesn’t matter)), in such cases I close the connection and try to connect again, after a certain interval.
So, after starting the service, I observe the following picture:
Then, after some time (apparently when the disconnects occurred):
Which subsequently (after 6 hours) leads to an error:go dial error on addr dial tcp socket: to many open files
i.e. socket is created? B connection, as it were, remains in a suspended state?
Although the connection is explicitly closed: conn.Close()
example code to understand what's what:
//Сбор данных - вызов в гоурутине
func stantionListener(server Servers, p DataProducer) {
//Основной цикл для сервера
for {
conn, err := net.Dial("tcp", "адрес сервера")
if err != nil {
log.Fatal("dial error on addr:", addr, err)
return
}
defer conn.Close()
//Цикл, в котором происходит обмен с сервером данными
for {
if wr, err := conn.Write([]byte("Запрос к серверу")); //Запрос #1
wr == 0 || err != nil {
log.Println(addr, err)
break
}
err = conn.SetReadDeadline(time.Now().Add(5 * time.Second))
if err != nil {
log.Println(addr, err)
break
}
//Пытаемся получить данные в ответ
buff := make([]byte, 1024)
rd, err := conn.Read(buff)
if err != nil{
log.Println(addr, err)
}
err = res.Parser(buff[:rd])
if err != nil {
log.Println(err, stDesc)
} else {
//Отправляем запрос о том, что все ок
if wr, err := conn.Write([]byte("ok, данные получил")); //Запрос #4
wr == 0 || err != nil {
log.Println(err, stDesc)
}
}
d := time.Duration(kpi.current * float32(time.Second))
time.Sleep(d)
}//end for
log.Println("error, when connect or receive data", stDesc, "wait 60seconds")
time.Sleep(time.Minute) //Ждем 1 минуту, прежде чем выполнить повторное подключение
}
}
Answer the question
In order to leave comments, you need to log in
Close the connection at the end of the first conn.Close() loop, as the defer is only executed when the method ends.
.....
d := time.Duration(kpi.current * float32(time.Second))
time.Sleep(d)
}//end for
conn.Close()
log.Println("error, when connect or receive data", stDesc, "wait 60seconds")
time.Sleep(time.Minute) //Ждем 1 минуту, прежде чем выполнить повторное подключение
}
}
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question