Функция recv () возвращает 0 и не может восстановить соединение с сервером, когда новый сокет создан после истечения времени ожидания - PullRequest
0 голосов
/ 16 марта 2020

У меня есть windows клиентское приложение TCP, которое подключается к порту и IP-адресу сервера. он подключается к серверу и работает нормально. это приложение отправляет данные каждые 2 секунды на сервер и получает ответ. Некоторое время в рабочем приложении recv () не получает никакого ответа и возвращает время ожидания 10060. Мы постоянно проверяем 3 раза, есть ли какой-либо ответ на функцию recv (), но он каждый раз возвращает 10060 времени ожидания. затем мы закрываем сокет и создаем новый сокет, чтобы начать новое соединение, но в это время recv () вернет ошибку 0 или 10054, но не сможет снова соединиться с сервером.

//INIT TCP

WSADATA wsaData;
int iResult;

SOCKET ConnectSocket = INVALID_SOCKET;
*ConnectSocketOut =    INVALID_SOCKET;
struct sockaddr_in clientService[MAX_PRINTERS];

    // Initialize Winsock
    iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (iResult != NO_ERROR) {
        return 1;
    }

//----------------------
// Create a SOCKET for connecting to server
ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_IP); //IPPROTO_TCP
if (ConnectSocket == INVALID_SOCKET) {
    WSACleanup();
    return 1;
}

//----------------------
// The sockaddr_in structure specifies the address family,
// IP address, and port of the server to be connected to.
clientService[Index].sin_family = AF_INET;
clientService[Index].sin_addr.s_addr = inet_addr(PortInformation[Index].IPAddress);     
     clientService[Index].sin_port = htons(PortInformation[Index].TCPPortNum);
//----------------------
// Connect to server.
WSASetLastError(0);
iResult = connect(ConnectSocket, (SOCKADDR*)&clientService[Index], sizeof(clientService[Index]));
if (iResult == SOCKET_ERROR) {
    int ErrSt = WSAGetLastError();
    closesocket(ConnectSocket);
    WSACleanup();
    ConnectSocket = INVALID_SOCKET;
    *ConnectSocketOut = ConnectSocket;
    return 1;
}
else
{
    *ConnectSocketOut = ConnectSocket;              
}

 //send data

int iResult = 0;
   if (ConnectSocketOut != INVALID_SOCKET)
   { 
     DWORD timeout = 10 * 1000;
      setsockopt(ConnectSocketOut, SOL_SOCKET, SO_SNDTIMEO, (char*)&timeout,   sizeof(timeout));
 iResult = send(ConnectSocketOut, lpBuffer, (int)dNoOFBytestoWrite, 0);
    }
    else
    {
        return FALSE;
    }
    if ((iResult == SOCKET_ERROR)||(iResult!= dNoOFBytestoWrite)) {
        int ErrorSt = WSAGetLastError();
        closesocket(ConnectSocketOut);
        WSACleanup();
        ConnectSocketOut = INVALID_SOCKET;
        return FALSE;
    }

    Status = TRUE;


   //Receive data

      int iResult = 0;
    do {

    if (ConnectSocketOut != INVALID_SOCKET) 
    {
              DWORD timeout = 10 * 1000;
              setsockopt(ConnectSocketOut, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout));


      iResult = recv(ConnectSocketOut, (char*)&ReceiveData[BytesReceived], 100, 0);
        }
        if (iResult > 0)
        {

BytesReceived += iResult;
   Status = ReceiveData[BytesReceived - 1];         
                  switch (Status)
            {
                case ACK:
                case NAK:
                {

                    AckStatus = ACK_FOUND;
                    break;
                }
                default:
                {
                    Status = UNKNOW_ACK;

                }
            }

        }
        else if (iResult == 0)
        {
            int RetVal = WSAGetLastError();
            Status = UNKNOW_ACK;
            break;
        }
        else
        {
            int RetVal = WSAGetLastError();
        }

    }while ((AckStatus == ACK_NOTFOUND) && (Counter++ < 4));
    if (Status == UNKNOW_ACK)
    {
        closesocket(ConnectSocketOut);
        WSACleanup();
        ConnectSocketOut = INVALID_SOCKET;
    }
    Sleep(1000); 
...