1

每次尝试使用此代码时,我都会收到 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. 我制作了一个新的 VS2010MULTI-BYTE用于测试,该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));

所以我必须将字符串从 转换UNICODEMULTI_BYTE

4

2 回答 2

1

调用时connect(),您需要使用sizeof(SOCKADDR_IN)orsizeof(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);
于 2013-05-30T15:36:09.363 回答
0

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

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

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

于 2013-05-30T15:19:34.940 回答