2016-09-20 330 views
-1
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

  • 發送失敗10093和
  • 關機失敗10093.

請讓我知道我可以在此代碼中更改哪些內容。

+1

這不是MATLAB語言。我正在移除標籤。我還強烈建議你閱讀[如何問](http://stackoverflow.com/help/how-to-ask)頁面,並相應地編輯你的問題,如果你想更好的機會得到答案。 – Hoki

+0

錯誤** 100093 **:表示「尚未成功執行WSAStartup」。你可以發佈[MCVE]嗎? – purplepsycho

+0

您是否考慮查找Winsock錯誤10093的含義? – EJP

回答

1

套接字錯誤10093(WSANOTINITIALIZED)指:

  1. WSAStartup()沒有被調用,或者它未能

  2. WSACleanup()被稱爲太多次。

在這種情況下,你的代碼是在地方致電WSACleanup()它不屬於:

  1. sConnect()電話WSACleanup()如果getaddrinfo()失敗

  2. sWrite()電話WSACleanup()如果send()失敗。

  3. ~socketClient()如果shutdown()失敗,則會調用WSACleanup()額外的時間。

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; 
     } 
    } 
};