如果设置了 UDP 源地址,则 WSASendMsg 返回错误 [英] WSASendMsg return error if set UDP source address
本文介绍了如果设置了 UDP 源地址,则 WSASendMsg 返回错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
类似于:如何在 Windows 上设置 UDP 源地址 它对我不起作用.无法设置源端口并出现错误:
Similar to: Howto set the UDP source address on Windows It doesn't work for me. Unable to setup source port and get error:
我已经创建了套接字:
bool CUDPTransport::OpenConnection(void) {
// Create UDP socket
this->m_hSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (this->m_hSocket == INVALID_SOCKET) {
return false;
}
// Success
return true;
}
并且我能够通过 UDP 传输发送:
and I am able to send by UDP transport:
bool CUDPTransport::SendMessage(const CString& sBuffer, const CSyslogOptions& oSyslogOptions) {
// Convert using the local code page
CT2A sASCII(sBuffer);
// Create address
struct sockaddr_in sin;
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_port = htons(this->m_nPort);
sin.sin_addr.s_addr = htonl(this->m_nCollectorIPv4);
// Create buffer to send
WSABUF oBuffer;
oBuffer.buf = sASCII.m_psz;
oBuffer.len = (int)strlen(sASCII.m_psz);
// Declare
char aControlData[WSA_CMSG_SPACE(sizeof(struct in_pktinfo))];
memset(&aControlData, 0, sizeof(aControlData));
// Create a message
WSAMSG oMessage;
memset(&oMessage, 0, sizeof(oMessage));
oMessage.name = (struct sockaddr*)&sin;
oMessage.namelen = sizeof(sin);
oMessage.lpBuffers = &oBuffer;
oMessage.dwBufferCount = 1;
/* TODO: set source address
oMessage.Control.buf = (char*)&aControlData;
oMessage.Control.len = sizeof(aControlData);
// Create messge header
WSACMSGHDR* oHeader = WSA_CMSG_FIRSTHDR(&oMessage);
// memset(oHeader, 0, WSA_CMSG_SPACE(sizeof(struct in_pktinfo)));
oHeader->cmsg_level = IPPROTO_IP;
oHeader->cmsg_type = IP_PKTINFO;
oHeader->cmsg_len = WSA_CMSG_LEN(sizeof(struct in_pktinfo));
struct in_pktinfo* pktinfo = (struct in_pktinfo*)WSA_CMSG_DATA(oHeader);
pktinfo->ipi_addr.s_addr = htonl(oSyslogOptions.m_nSenderIPv4);
*/
// Declare variable
unsigned long nSentBytes = 0;
// Send an initial buffer
int nResult = WSASendMsg(this->m_hSocket, &oMessage, 0, &nSentBytes, NULL, NULL);
if (nResult == SOCKET_ERROR) {
int nErrorNo = this->getSocketLastOSErrorNo();
CString sErrorMsg = this->getSocketLastOSErrorString(nErrorNo);
closesocket(this->m_hSocket);
return false;
}
return true;
}
当我想设置源 IP 地址时,我取消注释处理控制数据
When I wish to set up source IP address I uncomment working with control data
bool CUDPTransport::SendMessage(const CString& sBuffer, const CSyslogOptions& oSyslogOptions) {
// Convert using the local code page
CT2A sASCII(sBuffer);
// Create address
struct sockaddr_in sin;
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_port = htons(this->m_nPort);
sin.sin_addr.s_addr = htonl(this->m_nCollectorIPv4);
// Create buffer to send
WSABUF oBuffer;
oBuffer.buf = sASCII.m_psz;
oBuffer.len = (int)strlen(sASCII.m_psz);
// Declare
char aControlData[WSA_CMSG_SPACE(sizeof(struct in_pktinfo))];
memset(&aControlData, 0, sizeof(aControlData));
// Create a message
WSAMSG oMessage;
memset(&oMessage, 0, sizeof(oMessage));
oMessage.name = (struct sockaddr*)&sin;
oMessage.namelen = sizeof(sin);
oMessage.lpBuffers = &oBuffer;
oMessage.dwBufferCount = 1;
oMessage.Control.buf = (char*)&aControlData;
oMessage.Control.len = sizeof(aControlData);
// Create messge header
WSACMSGHDR* oHeader = WSA_CMSG_FIRSTHDR(&oMessage);
// memset(oHeader, 0, WSA_CMSG_SPACE(sizeof(struct in_pktinfo)));
oHeader->cmsg_level = IPPROTO_IP;
oHeader->cmsg_type = IP_PKTINFO;
oHeader->cmsg_len = WSA_CMSG_LEN(sizeof(struct in_pktinfo));
struct in_pktinfo* pktinfo = (struct in_pktinfo*)WSA_CMSG_DATA(oHeader);
pktinfo->ipi_addr.s_addr = htonl(oSyslogOptions.m_nSenderIPv4);
// Declare variable
unsigned long nSentBytes = 0;
// Send an initial buffer
int nResult = WSASendMsg(this->m_hSocket, &oMessage, 0, &nSentBytes, NULL, NULL);
if (nResult == SOCKET_ERROR) {
int nErrorNo = this->getSocketLastOSErrorNo();
CString sErrorMsg = this->getSocketLastOSErrorString(nErrorNo);
closesocket(this->m_hSocket);
return false;
}
return true;
}
并得到 errno: 10022 和消息的错误:提供了无效的参数".有人可以帮助我理解问题吗?谢谢!
and get error with errno: 10022 and message: "An invalid argument was supplied". Does anybody can help me to understand the problem? Thanks!
推荐答案
-1. 通过绑定解决的错误:
-1.Error resolved by bind:
bool CUDPTransport::OpenConnection(void) {
// Create UDP socket
this->m_hSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (this->m_hSocket == INVALID_SOCKET) {
return false;
}
// Create source address (2130706433 = 127.0.0.1)
struct sockaddr_in sin;
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_port = 0;
sin.sin_addr.s_addr = htonl(2130706433);
// Bind socker
int nResult = bind(this->m_hSocket, (struct sockaddr*)&sin, sizeof(sin));
if (nResult == SOCKET_ERROR) {
int nErrorNo = this->getSocketLastOSErrorNo();
CString sErrorMsg = this->getSocketLastOSErrorString(nErrorNo);
closesocket(this->m_hSocket);
return false;
}
// Success
return true;
}
-2.Send 方法工作正常.
-2.Send method is working fine.
bool CUDPTransport::SendMessage(const CString& sBuffer, const CSyslogOptions& oSyslogOptions) {
// Convert using the local code page
CT2A sASCII(sBuffer);
// Create address
struct sockaddr_in sin;
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_port = htons(this->m_nPort);
sin.sin_addr.s_addr = htonl(this->m_nCollectorIPv4);
// Create buffer to send
WSABUF oBuffer;
oBuffer.buf = sASCII.m_psz;
oBuffer.len = (int)strlen(sASCII.m_psz);
// Declare
char aControlData[WSA_CMSG_SPACE(sizeof(struct in_pktinfo))];
memset(&aControlData, 0, sizeof(aControlData));
// Create a message
WSAMSG oMessage;
memset(&oMessage, 0, sizeof(oMessage));
oMessage.name = (struct sockaddr*)&sin;
oMessage.namelen = sizeof(sin);
oMessage.lpBuffers = &oBuffer;
oMessage.dwBufferCount = 1;
oMessage.Control.buf = (char*)&aControlData;
oMessage.Control.len = sizeof(aControlData);
// Create message header
WSACMSGHDR* oHeader = WSA_CMSG_FIRSTHDR(&oMessage);
memset(oHeader, 0, WSA_CMSG_SPACE(sizeof(struct in_pktinfo)));
oHeader->cmsg_level = IPPROTO_IP;
oHeader->cmsg_type = IP_PKTINFO;
oHeader->cmsg_len = WSA_CMSG_LEN(sizeof(struct in_pktinfo));
struct in_pktinfo* pktinfo = (struct in_pktinfo*)WSA_CMSG_DATA(oHeader);
pktinfo->ipi_addr.s_addr = htonl(oSyslogOptions.m_nSenderIPv4);
// Declare variable
unsigned long nSentBytes = 0;
// Send an initial buffer
int nResult = WSASendMsg(this->m_hSocket, &oMessage, 0, &nSentBytes, NULL, NULL);
if (nResult == SOCKET_ERROR) {
int nErrorNo = this->getSocketLastOSErrorNo();
CString sErrorMsg = this->getSocketLastOSErrorString(nErrorNo);
closesocket(this->m_hSocket);
return false;
}
return true;
}
这篇关于如果设置了 UDP 源地址,则 WSASendMsg 返回错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文