Вопрос о winsock и IPv6
Я написал dll на C++ , которая позволяет мне выполнять функции Winsock из кода PowerBuilder.
Для IPv4 это отлично работает, но я получаю ошибку в IPv6. Я начинаю с функций UDP, потому что они проще. Следующая ошибка возникает на "Отправить":
Запрошенный адрес недействителен в его контексте
В приведенном ниже коде UD. family будет иметь значение AF_INET или AF_NET6.
Что я уже пробовал:
// method of_sendto (Unicode String) PBXRESULT winsock::fn_sendto_u(PBCallInfo * ci) { PBXRESULT pbxr = PBX_OK; SOCKET SendSocket = INVALID_SOCKET; sockaddr_in SendAddr4; sockaddr_in6 SendAddr6; USHORT port; int iResult = 0; LPCTSTR lpHostName = NULL; LPCTSTR lpMessage = NULL; int nBytes = 0, nLeft = 0, idx = 0; // get arguments pbstring arg0 = ci->pArgs->GetAt(0)->GetString(); lpHostName = ud.session->GetString(arg0); port = ci->pArgs->GetAt(1)->GetUint(); pbstring arg2 = ci->pArgs->GetAt(2)->GetString(); lpMessage = ud.session->GetString(arg2); nBytes = (int) _tcslen(lpMessage) * sizeof(TCHAR); // create a socket SendSocket = socket(ud.family, SOCK_DGRAM, IPPROTO_UDP); if (SendSocket == INVALID_SOCKET) { // set the return value ci->returnValue->SetBool(FALSE); return pbxr; } switch(ud.family) { case AF_INET: SendAddr4.sin_family = AF_INET; SendAddr4.sin_port = htons(port); InetPtonW(AF_INET, lpHostName, &SendAddr4.sin_addr); break; case AF_INET6: SendAddr6.sin6_family = AF_INET6; SendAddr6.sin6_port = htons(port); InetPtonW(AF_INET6, lpHostName, &SendAddr6.sin6_addr); break; } nLeft = nBytes; while (nLeft > 0) { // send the message switch(ud.family) { case AF_INET: iResult = sendto(SendSocket, (char*) lpMessage + idx, (int) nLeft, 0, (SOCKADDR *) &SendAddr4, sizeof(SendAddr4)); break; case AF_INET6: iResult = sendto(SendSocket, (char*) lpMessage + idx, (int) nLeft, 0, (SOCKADDR *) &SendAddr6, sizeof(SendAddr6)); break; } if (iResult == SOCKET_ERROR) { // save error and close socket iResult = WSAGetLastError(); closesocket(SendSocket); WSASetLastError(iResult); // set the return value ci->returnValue->SetBool(FALSE); return pbxr; } nLeft -= iResult; idx += iResult; } // close the socket closesocket(SendSocket); // set the return value ci->returnValue->SetBool(TRUE); return pbxr; }
Jochen Arndt
Передаете ли вы действительный IPv6-адрес?
Проверьте возвращаемое значение InetPton, чтобы убедиться в этом.
Roland M Smith
Я добавил код для проверки возврата из InetPton, и он работает. Я передаю действительный IP-адрес версии 6. Сообщение об ошибке поступает от "отправить".