2013-05-07 28 views
1

我想讓我的套接字「基於事件」。以下是我的嘗試:通過使插座事件驅動使udp套接字非阻塞

VOID createServerSocket() 
{ 
    WSADATA wsa; 

    //Initialise winsock// 
    if (WSAStartup(MAKEWORD(2,2),&wsa) != 0) 
     { 

     //"WinSock Initialization FAILED", 

     } 

    //Create a socket// 

    SOCKET newSocketIdentifier; 
    SOCKADDR_IN newSocket; 

    if((newSocketIdentifier = socket(AF_INET , SOCK_DGRAM , 0)) == INVALID_SOCKET) 
     {     

     //Socket Creation Failed 

     } 
    //Socket Created// 

    //Prepare the sockaddr_in structure// 
    newSocket.sin_family = AF_INET; 
    newSocket.sin_addr.s_addr = INADDR_ANY; 
    newSocket.sin_port = htons(8888); 

    //Bind// 
    if(bind(newSocketIdentifier ,(struct sockaddr *)&newSocket, sizeof(SOCKADDR_IN)) == SOCKET_ERROR) 
     { 
     //Bind Failed 
     } 

    //Bind Done// 

    WSAEVENT NewEvent = WSACreateEvent(); 
    WSAEventSelect(newSocketIdentifier, NewEvent, FD_READ | FD_WRITE); //made the socket "newSocketIdentifier" event based for events "FD_READ" and FD_WRITE 

} 

我不知道如何進一步處理。我應該如何檢查是否有任何期望的事件發生?我怎樣才能不斷地檢查這些事件?這將在一段時間(1)循環?

我在互聯網上找到的所有例子都是針對多個套接字的。但是,在我的情況下,我只有一個套接字,我想讓它成爲「事件驅動」讀寫。請幫幫我。我卡住了!

+1

是的,你需要循環連續檢查事件和是選擇應該是用於多個套接字非阻塞。 – shazin 2013-05-07 06:55:38

+0

@shazin:你能分享一些如何處理這些事件的例子嗎?我正在使用一個套接字而不是多個套接字。 – Ayse 2013-05-07 09:38:44

+1

你在這裏沒有做任何事情。您正在通過阻塞I/O疊加多路複用的I/O。讀取和寫入操作可能仍會阻止。 – EJP 2013-05-07 10:13:16

回答

1

假設您想要偵聽進入的UDP數據包,請嘗試使用以下代碼段並查看。

/ Initialize Winsock. 
WSADATA wsaData; 
int iResult = WSAStartup(MAKEWORD(2,2), &wsaData); 
if (iResult != NO_ERROR) 
    printf("Error at WSAStartup()\n"); 

// Create a socket. 
SOCKET m_socket[1]; 
m_socket[0] = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); 

if (m_socket[0] == INVALID_SOCKET) { 
    printf("Error at socket(): %ld\n", WSAGetLastError()); 
    WSACleanup(); 
    return; 
} 

// Bind the socket. 
sockaddr_in service[1]; 

service[0].sin_family = AF_INET; 
service[0].sin_addr.s_addr = INADDR_ANY; 
service[0].sin_port = htons(8888); 

if (bind(m_socket[0], (SOCKADDR*) &service[0], sizeof(service[0])) == SOCKET_ERROR) { 
    printf("bind() failed.\n"); 
    closesocket(m_socket[0]); 
    return; 
} 

char data[256]; 
int bytes, waitRet; 

WSAEVENT hEvent = WSACreateEvent(); 
WSANETWORKEVENTS events; 
WSAEventSelect(*m_socket, hEvent, FD_READ | FD_WRITE); 
while(1) 
{ 
    waitRet = WSAWaitForMultipleEvents(2, &hEvent, FALSE, WSA_INFINITE, FALSE); 
    if(WSAEnumNetworkEvents(*m_socket,hEvent,&events) == SOCKET_ERROR) 
    { 
     cout << "Error"; 
    } 
    else 
    { 
     if(events.lNetworkEvents & FD_READ) 
     { 
      bytes = recv(*m_socket, data, 256, 0); 
      cout << data << endl; 
     } 
    } 
} 

WSACloseEvent(hEvent); 
+0

+1的幫助:)它工作正常 – Ayse 2013-05-07 11:08:22

+0

古代歷史我知道,但WSAWaitForMultipleEvents()的第一個參數應該是1,而不是2! – 2017-02-04 16:10:49