我正在編寫用於處理基本操作(如連接,發送和接收數據)的UDP套接字類的C++代碼。我嘗試使用WSAEventSelect的網絡事件機制來處理與套接字相關的基本操作。 當我使用WSASend將數據發送到接收數據的(UDP)目的地時,一切都很順利。 但是,當我使用WSASend將數據發送到不存在的目標(UDP)或無法通過網絡訪問時,我會觸發FD_READ事件。這當然會導致嚴重的問題,因爲沒有實際的數據可以接收!WSASend for UDP套接字觸發器FD_READ當沒有可用的目標時
我無法解釋爲什麼會發生這種情況 - 有什麼想法?
也許我做錯了什麼,這裏是我的代碼相關部分:
WSADATA m_wsaData ;
SOCKET m_Socket ;
WSAEVENT m_SocketEvent ;
if(WSAStartup(MAKEWORD(2,2), &m_wsaData) != 0)
{
// some error
}
// Create a new socket to receive datagrams on
struct addrinfo hints, *res = NULL ;
int rc ;
memset(&hints, 0, sizeof(hints)) ;
hints.ai_family = AF_UNSPEC ;
hints.ai_socktype = SOCK_DGRAM ;
hints.ai_protocol = IPPROTO_UDP ;
rc = getaddrinfo("SomePC", "3030", &hints, &res) ;
if(rc == WSANO_DATA)
{
// some error
}
if ((m_Socket = WSASocket(res->ai_family, res->ai_socktype, res->ai_protocol, NULL, 0, 0)) == INVALID_SOCKET)
{
// some error
}
// create event and associate it with the socket
m_SocketEvent = WSACreateEvent() ;
if(m_SocketEvent == WSA_INVALID_EVENT)
{
// some error
}
// associate only the following events: close, read, write
if(SOCKET_ERROR == WSAEventSelect(m_Socket, m_SocketEvent, FD_CLOSE+FD_READ+FD_WRITE))
{
// some error
}
// connect to a server
int ConnectRet = WSAConnect(m_Socket, (SOCKADDR*)res->ai_addr, res->ai_addrlen, NULL, NULL, NULL, NULL) ;
if(ConnectRet == SOCKET_ERROR)
{
// some error
}
然後,每當我嘗試通過套接字發送一些數據沒有被監聽或(UDP套接字)目的地無法達到我總是得到FD_READ觸發:
char buf[32] ; // some data to send...
WSABUF DataBuf;
DataBuf.len = 32;
DataBuf.buf = (char*)&buf;
DWORD NumBytesActualSent ;
if(SOCKET_ERROR == WSASend(m_Socket, &DataBuf, 1, &NumBytesActualSent,0,0,0))
{
if(WSAGetLastError() == WSAEWOULDBLOCK) // non-blocking socket - wait for send ok ?
{
// handle WSAEWOULDBLOCK...
}
else
{
// some error
return ;
}
}
int ret = WSAWaitForMultipleEvents(1, &m_SocketEvent, FALSE, INFINITE, FALSE) ;
if(ret == WAIT_OBJECT_0)
{
WSANETWORKEVENTS NetworkEvents ;
ZeroMemory(&NetworkEvents, sizeof(NetworkEvents)) ;
if(SOCKET_ERROR == WSAEnumNetworkEvents(m_Socket, m_SocketEvent, &NetworkEvents))
{
return ; // some error
}
if(NetworkEvents.lNetworkEvents & FD_READ) // Read ?
{
if(NetworkEvents.iErrorCode[FD_READ_BIT] != 0) // read not ok ?
{
// some error
}
else
{
TRACE("Read Event Triggered ! - Why ? ? ? ? ? ? ?\n") ;
}
}
}
任何幫助或見解將是最appriciated! 謝謝, 阿米特C.
也許這就是您收到的ICMP信息(即Destination Unreachable)?檢查標題,這是一個開始的地方。 – KBart
通過檢查標題(如何做),你的意思是什麼?我試圖調用WSARecv來讀取這種情況下的數據,但得到錯誤10054(「... connection was closed ...」),使用帶有FIONREAD的ioctlsocket我得到1 - meaninng我有1個字節可用於套接字接收 - 但再次WSARecv失敗。 – user1852490