发送失败,错误10093,关闭失败,错误10093

时间:2016-09-20 09:31:11

标签: sockets

class socketClient
{
    private:
    SOCKET ConnectSocket;
    int numBlock;

    public:     
    socketClient()
    {
        WSADATA wsaData;
        numBlock = countObj;
        ++countObj; 
        int iResult;

        // Initialize Winsock

            iResult = WSAStartup(MAKEWORD(2,2), &wsaData);

            if (iResult != 0) 
            {                
                ssPrintf("WSAStartup failed: %d\n", iResult);
                //return 1;
            }

        // Create a SOCKET for connecting to server
        ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

        if (ConnectSocket == INVALID_SOCKET) 
        {
            ssPrintf("Error at socket(): %ld\n", WSAGetLastError());
            //freeaddrinfo(result);
            WSACleanup();
            //return 1;
        }
    }

    void sConnect(char* myHost, int myPort)
    {
        int iResult;
        char port[5];
        struct addrinfo *result = NULL,
                        *ptr = NULL,
                        hints;
        ZeroMemory( &hints, sizeof(hints) );
        hints.ai_family = AF_INET;
        hints.ai_socktype = SOCK_STREAM;
        hints.ai_protocol = IPPROTO_TCP;
        _itoa_s(myPort,port,5,10);
        iResult = getaddrinfo(myHost, porgt, &hints, &result);

        if ( iResult != 0 ) 
        {
            ssPrintf("getaddrinfo failed: %d\n", iResult);
            WSACleanup();
            //return 1;
        }

        // Connect to server.
        iResult = connect( ConnectSocket, result->ai_addr, (int)result->ai_addrlen);
        if (iResult == SOCKET_ERROR) 
        {
            closesocket(ConnectSocket);
            ConnectSocket = INVALID_SOCKET;
        }
    }

    ~socketClient()
    {
        int iResult;
        --countObj;
        iResult = shutdown(ConnectSocket, SD_SEND);
        if (iResult == SOCKET_ERROR) 
        {
            printf("shutdown failed: %d\n", WSAGetLastError());
            closesocket(ConnectSocket);
            WSACleanup();

            //return 1;
        }

        closesocket(ConnectSocket);
        WSACleanup();
    }

    int getNumBlock()
    {
        return numBlock;
    }

    int sWrite(std::string str)
    {
        int iResult;
         // Send an string
        iResult = send( ConnectSocket, str.c_str(), str.size(), 256 );
        if (iResult == SOCKET_ERROR) 
        {
            ssPrintf("send failed: %d\n", WSAGetLastError());
            closesocket(ConnectSocket);
            WSACleanup();
            //return 1;
        }

        return iResult; //pocet odeslanych bytu
    }
};

我正在尝试将字符串发送到客户端模型,但在运行模型时,我收到错误:

  • 发送失败的10093和
  • 关闭失败10093。

请让我知道我可以在此代码中更改哪些内容。

1 个答案:

答案 0 :(得分:1)

套接字错误10093(WSANOTINITIALIZED)表示:

  1. WSAStartup()尚未被调用,或者失败

  2. WSACleanup()被调用了太多次。

  3. 在这种情况下,您的代码在不属于的地方调用WSACleanup()

      如果sConnect()失败,则
    1. WSACleanup()来电getaddrinfo()

    2. 如果sWrite()失败,则
    3. WSACleanup()调用send()

    4. 如果~socketClient()失败,
    5. WSACleanup()会额外拨打shutdown()

    6. 必须平衡

      WSAStartup()WSACleanup()。对于WSAStartup()的每次成功来电,您必须只调用WSACleanup() 一次。在这种情况下,只有析构函数应该调用WSACleanup(),并且只有WSAStartup()在构造函数中成功。

      您的代码中也包含其他错误。

      尝试更像这样的东西:

      class socketClient
      {
      private:
          SOCKET ConnectSocket;
          int numBlock;
          bool WSAInitialized;
      
          // private to prevent copies
      
          socketClient(const socketClient&)
              : ConnectSocket(INVALID_SOCKET), WSAInitialized(false)
          {
              numBlock = countObj++;
          }
      
          socketClient& operator=(const socketClient&)
          {
              return *this;
          }
      
      public:     
          socketClient()
              : ConnectSocket(INVALID_SOCKET), WSAInitialized(false)
          {
              numBlock = countObj++;
      
              // Initialize Winsock
      
              WSADATA wsaData;
              int iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
              if (iResult != 0) 
              {                
                  ssPrintf("WSAStartup() failed: %d\n", iResult);
                  return;
              }
      
              WSAInitialized = true;
      
              // Create a SOCKET for connecting to server
              ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
              if (ConnectSocket == INVALID_SOCKET) 
              {
                  ssPrintf("socket() failed: %d\n", WSAGetLastError());
                  return;
              }
          }
      
          ~socketClient()
          {
              --countObj;
      
              if (ConnectSocket != INVALID_SOCKET)
              {
                  shutdown(ConnectSocket, SD_SEND);
                  closesocket(ConnectSocket);
              }
      
              if (WSAInitialized)
                  WSACleanup();
          }
      
          bool sConnect(char* myHost, int myPort)
          {
              char port[6];
              struct addrinfo *result = NULL,
                              hints;
      
              ZeroMemory( &hints, sizeof(hints) );
              hints.ai_family = AF_INET;
              hints.ai_socktype = SOCK_STREAM;
              hints.ai_protocol = IPPROTO_TCP;
              _itoa_s(myPort, port, 6, 10);
      
              int iResult = getaddrinfo(myHost, port, &hints, &result);
              if (iResult != 0)
              {
                  ssPrintf("getaddrinfo() failed: %d\n", iResult);
                  return false;
              }
      
              // Connect to server.
              if (connect(ConnectSocket, result->ai_addr, (int)result->ai_addrlen) == SOCKET_ERROR) 
              {
                  ssPrintf("connect() failed: %d\n", WSAGetLastError());
                  freeaddrinfo(result);
                  return false;
              }
      
              freeaddrinfo(result);
              return true;
          }
      
          int getNumBlock()
          {
              return numBlock;
          }
      
          bool sWrite(const std::string &str)
          {
              int iResult;
              const char *ptr = str.c_str();
              int len = str.size();
      
              // Send an string
              while (len > 0)
              {
                  iResult = send( ConnectSocket, ptr, len, 0 );
                  if (iResult == SOCKET_ERROR) 
                  {
                      ssPrintf("send() failed: %d\n", WSAGetLastError());
                      return false;
                  }
      
                  ptr += iResult;
                  len -= iResult;
              }
      
              return true;
          }
      };
      

      由于您使用C ++进行编码,因此您应该考虑使用异常和RAII技术,例如:

      #include <stdexcept>
      #include <memory>
      
      class winsock_error : public std::runtime_error
      {
      public:
          int errorCode;
      
          winsock_error(const std::string &msg, int error)
              : std::runtime_error(msg), errorCode(error)
          {
          }
      };
      
      class wsaInit
      {
      private:
          void init()
          {
              WSADATA wsaData;
              int iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
              if (iResult != 0) 
                  throw winsock_error("WSAStartup() failed", iResult);
          }
      
      public:
          wsaInit()
          {
              init();
          }
      
          wsaInit(const wsaInit &)
          {
              init();
          }
      
          ~wsaInit()
          {
              WSACleanup();
          }
      };
      
      struct socketDeleter
      {
          typedef SOCKET pointer;
      
          void operator()(SOCKET s)
          {
              if (s != INVALID_SOCKET)
              {
                  shutdown(s, SD_BOTH);
                  closesocket(s);
              }
          }
      };
      
      typedef std::unique_ptr<SOCKET, socketDeleter> socket_ptr;
      typedef std::unique_ptr<struct addrinfo, decltype(&freeaddrinfo)> addrinfo_ptr;
      
      class socketClient
      {
      private:
          wsaInit wsa;
          socket_ptr ConnectSocket;
          int numBlock;
      
      public:     
          socketClient()
              : ConnectSocket(INVALID_SOCKET)
          {
              numBlock = countObj++;
          }
      
          socketClient(const socketClient&) = delete;
      
          socketClient& operator=(const socketClient&) = delete;
      
          ~socketClient()
          {
              --countObj;
          }
      
          void sConnect(char* myHost, int myPort)
          {
              char port[6];
              struct addrinfo *result = NULL,
                              hints;
      
              ZeroMemory( &hints, sizeof(hints) );
              hints.ai_family = AF_INET;
              hints.ai_socktype = SOCK_STREAM;
              hints.ai_protocol = IPPROTO_TCP;
              _itoa_s(myPort, port, 6, 10);
      
              int iResult = getaddrinfo(myHost, port, &hints, &result);
              if (iResult != 0)
                  throw winsock_error("getaddrinfo() failed", iResult);
      
              addrinfo_ptr result_ptr(result, &::freeaddrinfo);
      
              // Connect to server.
              int errorCode = 0;
              for(struct addrinfo *ptr = result; ptr != NULL; ptr = ptr->ai_next)
              {
                  // Create a SOCKET for connecting to server
                  socket_ptr sock( socket(result->ai_family, result->ai_socktype, result->ai_protocol) );
                  if (sock.get() == INVALID_SOCKET) 
                      throw winsock_error("socket() failed", WSAGetLastError());
      
                  if (connect(sock.get(), result->ai_addr, (int)result->ai_addrlen) != SOCKET_ERROR)
                  {
                      ConnectSocket = std::move(sock);
                      return;
                  }
      
                  errorCode = WSAGetLastError();
              }
      
              throw winsock_error("connect() failed", errorCode);
          }
      
          int getNumBlock()
          {
              return numBlock;
          }
      
          void sWrite(const std::string &str)
          {
              int iResult;
              const char *ptr = str.c_str();
              int len = str.size();
      
              // Send an string
              while (len > 0)
              {
                  iResult = send(ConnectSocket.get(), ptr, len, 0);
                  if (iResult == SOCKET_ERROR) 
                      throw winsock_error("send() failed", WSAGetLastError());
                  ptr += iResult;
                  len -= iResult;
              }
          }
      };