Сбой соединения TCP - PullRequest
       4

Сбой соединения TCP

0 голосов
/ 11 октября 2010

У меня проблемы с простым сокетом TCP с функцией connect () и read ().Эта программа работает, если я запускаю сервер первым, а клиент - вторым.Однако, когда я сначала запускаю клиент, он продолжает пытаться подключиться к серверу, затем, когда я запускаю сервер, он подключается, но последующее чтение возвращает 0 байтов.Это говорит о том, что сервер закрыл сокет, но операторы отладки не поддерживают это.

Я пытаюсь, чтобы клиент постоянно пытался подключиться к серверу через порт 6380, а затем считывать данные.Если соединение потеряно, клиент попытается подключиться снова.У меня есть SO_REUSEADDR для сокетов.Что-то еще мне не хватает?

Исходный код для сервера

//***** SERVER *****
#include <iostream>
#include "SocketAdapter.h"
#include "SocketServer.h"
#include <errno.h>
#include <string.h>

unsigned char buffer[] = "123123123";

int main()
{
   SocketAdapter  socket;
   SocketServer   server(6380);

   server.Start();
   std::cout << "Wait for Connection" << std::endl;
   server.WaitForConnection(socket);
   std::cout << "Start to Send Data" << std::endl;

   while(1)
   {
      std::cout << "Sending Data   ";
      int bytesSent = socket.Send(buffer, 10);
      std::cout << "byteSent = " << bytesSent << std::endl;
      if (bytesSent == -1)
      {
         std::cout << "Errno (" << errno << ") - " << strerror(errno) << std::endl;
      }

      sleep(1);
   }//end while

   std::cout << "Ending Server" << std::endl;
   socket.Close();

   return 0;
}

Исходный код для клиента

// ***** SIMPLE CLIENT ******
#include <iostream>
#include "SocketAdapter.h"
#include "SocketClient.h"
#include <string.h>
#include <errno.h>

int main()
{
   SocketAdapter  socket;
   SocketClient   client(6380, "127.0.0.1");

   unsigned char buffer[1024];


   while(1)
   {
      client.Start();

      //Loop till we connect to Server
      while( !client.Connect(socket) )
      {
         std::cout << "Trying to connect to server." << std::endl;
         sleep(1);
      }

      std::cout << "Connected to Server" << std::endl;

      //Read till we get a timeout
      while(1)
      {
         int bytesRead = socket.Recv(buffer, 10,2000);
         if (bytesRead != 10)
         {
            std::cout << "   Failed to Read" << std::endl;
            std::cout << "   bytesRead = " << bytesRead << std::endl;
            std::cout << "   Errno (" << errno << ") - "
                      << strerror(errno) << std::endl;
            break;
         }

         std::cout << "buffer = " << buffer << std::endl;
         usleep(250000);
      }

      std::cout << "Something went wrong, restart" << std::endl;
   }

   return 0;
}

ВЫХОД СЕРВЕРА

./Server 
Wait for Connection
Start to Send Data
Sending Data   byteSent = 10

ВЫХОД КЛИЕНТА

./Client 
Trying to connect to server.
Trying to connect to server.
Connected to Server
   Failed to Read
   bytesRead = 0
   Errno (107) - Transport endpoint is not connected
Something went wrong, restart
Close Socket
Close Socket File Descriptor
Connected to Server
Trying to Recv on a closed socket
Return Value = -1
Errno        = Connection reset by peer

   Failed to Read
   bytesRead = -3
   Errno (104) - Connection reset by peer
Something went wrong, restart
Close Socket
Close Socket File Descriptor
Socket cannot shutdown!
Return Value = -1
Errno        = Transport endpoint is not connected

Trying to connect to server.
Close Socket
Close Socket File Descriptor
Socket cannot shutdown!
Return Value = -1
Errno        = Transport endpoint is not connected

1 Ответ

1 голос
/ 11 октября 2010

Возврат 0 прочитанных байтов из сокета совершенно законно. Это только означает, что вам нужно подождать и повторить попытку.

Например, посмотрите на эту read_data () функцию . Он проверяет, является ли количество прочитанных байтов > 0, и сохраняет их. Он проверяет, является ли число прочитанных байтов < 0, тогда это ошибка.

Случай 0 не очень большой успех, конечно, но не провал. Просто попробуйте еще раз. Я не анализировал ваш код очень подробно, поэтому может быть что-то еще, но эта важная ошибка часто допускается. (Кроме того, что в этих классах не показано?)

То, что вы можете посмотреть, это неблокирующие сокеты. Также см. FAQ, чтобы узнать, как определить, закрыт ли сокет на другом конце. И, возможно, рассмотрите возможность явного обнаружения завершения передачи с помощью отправки и окончания файла или маркера .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...