Winsock connect()错误10051

时间:2013-05-30 15:10:58

标签: c++ visual-studio-2010 winsock

每次尝试使用此代码时,都会出现10051套接字错误:

    USES_CONVERSION;
LPTSTR addr = A2W("192.168.1.209");
m_pSMACLPRCli = new CSMACLPRCli(addr, 12010, m_hWnd);
m_pSMACLPRCli->StartThread();

这是m_pSMACLPRCli的构造函数:

CSMACLPRCli::CSMACLPRCli(LPTSTR lpsztIPAddress, int nPort, HWND hParentWnd)

这就是我创建套接字并连接的方式:

void CBlockingSocket::Create(int nType /* = SOCK_STREAM */)
{
    ASSERT(m_hSocket == NULL);
    if ((m_hSocket = socket(AF_INET, nType, 0)) == INVALID_SOCKET)
    {
       TRACE("\n Socket Error !1 (%d)\n", WSAGetLastError());
       int err = WSAGetLastError();
}
}


BOOL CBlockingSocket::Connect(LPCSOCKADDR psa)
{
   ASSERT(m_hSocket != NULL);
   // should timeout by itself
   if (connect(m_hSocket, psa, sizeof(SOCKADDR)) == SOCKET_ERROR)
   {
       int nLastErr = WSAGetLastError();
       return FALSE;
   }

   return TRUE;
}

真正有趣的是,当我在VS2008项目中使用完全相同的代码,类结构等时,一切都按预期工作,但是当我在VS2010项目中使用它时,connect()我得到了一个10051错误,Network is unreachable

编辑:原版VS2010项目。是使用UNICODE编译的。我使用MULTI-BYTE进行了新的VS2010测试,connect()方法没有返回任何错误,并且......连接。我将地址字符串传递给构造函数的方式可能有问题吗?

USES_CONVERSION;
LPTSTR addr = A2W("192.168.1.209");
m_pSMACLPRCli = new CSMACLPRCli(addr, 12010, m_hWnd);
m_pSMACLPRCli->StartThread();

解决:

真正的问题不是connect()方法,而是与我将地址字符串传递给sockaddr对象的构造函数的方式有关。

构造函数:

CSockAddr(const char *pchIP, const USHORT ushPort = 0) // dotted IP addr string
{
    sin_family = AF_INET;
    sin_port = htons(ushPort);
    sin_addr.s_addr = inet_addr(pchIP);
}

我使用的构造函数调用:

 CString m_strSrvIPAddr;    
 CSockAddr saServer((char *) LPTSTR(LPCTSTR(m_strSrvIPAddr)), USHORT(m_nPort));

我改变了对此的调用:

CStringA strAddr(m_strSrvIPAddr);
CSockAddr saServer((const char *) strAddr, USHORT(m_nPort));

所以我必须将字符串从UNICODE转换为MULTI_BYTE

2 个答案:

答案 0 :(得分:1)

在致电connect()时,您需要使用sizeof(SOCKADDR_IN)sizeof(SOCKADDR_IN6),具体取决于psa实际指向的内容。我建议让调用者传递实际大小值:

BOOL CBlockingSocket::Connect(LPCSOCKADDR psa, int sasize)
{
   ASSERT(m_hSocket != INVALID_SOCKET);
   // should timeout by itself
   if (connect(m_hSocket, psa, sasize) == SOCKET_ERROR)
   {
       int nLastErr = WSAGetLastError();
       return FALSE;
   }

   return TRUE;
}

SOCKADDR_IN sa;
...
Connect((LPSOCKADDR)&sa, sizeof(sa));

或者,最好使用SOCKADDR_STORAGE,然后在将其传递给connect()时输入:

BOOL CBlockingSocket::Connect(const SOCKADDR_STORAGE *psa)
{
   ASSERT(m_hSocket != INVALID_SOCKET);
   // should timeout by itself
   if (connect(m_hSocket, (LPCSOCKADDR)psa, sizeof(SOCKADDR_STORAGE)) == SOCKET_ERROR)
   {
       int nLastErr = WSAGetLastError();
       return FALSE;
   }

   return TRUE;
}

SOCKADDR_STORAGE sa;
...
Connect(&sa);

答案 1 :(得分:0)

似乎此问题与您的代码或开发环境无关,而是与计算机所连接的网络有关。

ipconfig的输出将让您知道您的IP地址和子网掩码,这将使您了解您所属的网络。

192.186.0.0网络是本地地址(在NAT后面),除非您是其中的一部分,否则您将无法连接到此网络上的地址。如果您的IP地址不是以192.168开头,则是您收到错误的原因。