Fungsi WSAWaitForMultipleEvents (winsock2.h)
Fungsi WSAWaitForMultipleEvents kembali ketika satu atau semua objek peristiwa yang ditentukan berada dalam status tersinyal, ketika interval waktu habis berakhir, atau ketika rutinitas penyelesaian I/O telah dijalankan.
Sintaks
DWORD WSAAPI WSAWaitForMultipleEvents(
[in] DWORD cEvents,
[in] const WSAEVENT *lphEvents,
[in] BOOL fWaitAll,
[in] DWORD dwTimeout,
[in] BOOL fAlertable
);
Parameter
[in] cEvents
Jumlah handel objek peristiwa dalam array yang ditunjukkan oleh lphEvents. Jumlah maksimum penanganan objek peristiwa adalah WSA_MAXIMUM_WAIT_EVENTS. Satu atau beberapa peristiwa harus ditentukan.
[in] lphEvents
Penunjuk ke array handel objek peristiwa. Array dapat berisi handel objek dari berbagai jenis. Ini mungkin tidak berisi beberapa salinan handel yang sama jika parameter fWaitAll diatur ke TRUE. Jika salah satu handel ini ditutup saat penantian masih tertunda, perilaku WSAWaitForMultipleEvents tidak terdefinisi.
Handel harus memiliki hak akses SYNCHRONIZE . Untuk informasi selengkapnya, lihat Hak Akses Standar.
[in] fWaitAll
Nilai yang menentukan jenis tunggu. Jika TRUE, fungsi akan kembali saat status semua objek dalam array lphEvents diberi sinyal. Jika FALSE, fungsi akan kembali saat salah satu objek peristiwa diberi sinyal. Dalam kasus terakhir, nilai pengembalian dikurangi WSA_WAIT_EVENT_0 menunjukkan indeks objek peristiwa yang statusnya menyebabkan fungsi dikembalikan. Jika lebih dari satu objek peristiwa menjadi sinyal selama panggilan, ini adalah indeks array ke objek peristiwa yang disinyalir dengan nilai indeks terkecil dari semua objek peristiwa yang disinyalir.
[in] dwTimeout
Interval waktu habis, dalam milidetik. WSAWaitForMultipleEvents mengembalikan jika interval waktu habis kedaluwarsa, bahkan jika kondisi yang ditentukan oleh parameter fWaitAll tidak terpenuhi. Jika parameter dwTimeout adalah nol, WSAWaitForMultipleEvents menguji status objek peristiwa yang ditentukan dan segera kembali. Jika dwTimeoutWSA_INFINITE, WSAWaitForMultipleEvents menunggu selamanya; artinya, interval waktu habis tidak pernah kedaluwarsa.
[in] fAlertable
Nilai yang menentukan apakah utas ditempatkan dalam status tunggu yang dapat diperingatkan sehingga sistem dapat menjalankan rutinitas penyelesaian I/O. Jika TRUE, utas ditempatkan dalam status tunggu yang dapat diperingatkan dan WSAWaitForMultipleEvents dapat kembali ketika sistem menjalankan rutinitas penyelesaian I/O. Dalam hal ini, WSA_WAIT_IO_COMPLETION dikembalikan dan peristiwa yang sedang ditunggu belum disinyalir. Aplikasi harus memanggil fungsi WSAWaitForMultipleEvents lagi. Jika FALSE, utas tidak ditempatkan dalam status tunggu yang dapat diperingatkan dan rutinitas penyelesaian I/O tidak dijalankan.
Mengembalikan nilai
Jika fungsi WSAWaitForMultipleEvents berhasil, nilai pengembalian setelah berhasil adalah salah satu nilai berikut.
Tampilkan Nilai | Makna |
---|---|
|
Jika parameter fWaitAllTRUE, nilai pengembalian menunjukkan bahwa semua objek peristiwa yang ditentukan diberi sinyal.
Jika parameter fWaitAllFALSE, nilai yang dikembalikan dikurangi WSA_WAIT_EVENT_0 menunjukkan indeks array lphEvents dari objek peristiwa bersinyali yang memenuhi penantian. Jika lebih dari satu objek peristiwa menjadi sinyal selama panggilan, nilai pengembalian menunjukkan indeks array lphEvents dari objek peristiwa yang disinyalir dengan nilai indeks terkecil dari semua objek peristiwa yang disinyalir. |
|
Penantian berakhir dengan satu atau beberapa rutinitas penyelesaian I/O yang dijalankan. Peristiwa yang sedang ditunggu-tunggu belum disinyalir. Aplikasi harus memanggil fungsi WSAWaitForMultipleEvents lagi. Nilai yang dikembalikan ini hanya dapat dikembalikan jika parameter fAlertable adalah TRUE. |
|
Interval waktu habis berlalu dan kondisi yang ditentukan oleh parameter fWaitAll tidak terpenuhi. Tidak ada rutinitas penyelesaian I/O yang dijalankan. |
Jika fungsi WSAWaitForMultipleEvents gagal, nilai yang dikembalikan WSA_WAIT_FAILED. Tabel berikut ini mencantumkan nilai yang bisa digunakan dengan WSAGetLastError untuk mendapatkan informasi kesalahan yang diperluas.
Kode kesalahan | Makna |
---|---|
WSANOTINITIALISED | Panggilan WSAStartup yang berhasil harus terjadi sebelum menggunakan fungsi ini. |
WSAENETDOWN | Subsistem jaringan gagal. |
WSAEINPROGRESS | Pemblokiran panggilan Windows Sockets 1.1 sedang berlangsung, atau penyedia layanan masih memproses fungsi panggilan balik. |
WSA_NOT_ENOUGH_MEMORY | Memori bebas tidak cukup tersedia untuk menyelesaikan operasi. |
WSA_INVALID_HANDLE | Satu atau beberapa nilai dalam array lphEvents bukan handel objek peristiwa yang valid. |
WSA_INVALID_PARAMETER | Parameter cEvents tidak berisi jumlah handel yang valid. |
Keterangan
Fungsi WSAWaitForMultipleEvents menentukan apakah kriteria tunggu telah terpenuhi. Jika kriteria belum terpenuhi, utas panggilan memasuki status tunggu. Ini tidak menggunakan waktu prosesor sambil menunggu kriteria terpenuhi.
Fungsi WSAWaitForMultipleEvents kembali ketika salah satu atau semua objek yang ditentukan berada dalam status disinyalir, atau ketika interval waktu habis berlalu.
Ketika parameter bWaitAllTRUE, operasi tunggu selesai hanya ketika status semua objek telah diatur ke sinyal. Fungsi tidak mengubah status objek yang ditentukan sampai status semua objek telah diatur ke sinyal.
Ketika parameter bWaitAllFALSE, WSAWaitForMultipleEvents memeriksa handel dalam array lphEvents agar dimulai dengan indeks 0, hingga salah satu objek diberi sinyal. Jika beberapa objek menjadi sinyal, fungsi mengembalikan indeks handel pertama dalam array lphEvents yang objeknya diberi sinyal.
Fungsi ini juga digunakan untuk melakukan tunggu yang dapat diperingatkan dengan mengatur parameter fAlertable ke TRUE. Ini memungkinkan fungsi untuk kembali ketika sistem menjalankan rutinitas penyelesaian I/O oleh utas panggilan.
Utas harus dalam status tunggu yang dapat diperingatkan agar sistem menjalankan rutinitas penyelesaian I/O (panggilan prosedur asinkron atau APC). Jadi jika aplikasi memanggil WSAWaitForMultipleEvents ketika ada operasi asinkron yang tertunda yang memiliki rutinitas penyelesaian I/O dan parameter fAlertableadalah FALSE, maka rutinitas penyelesaian I/O tersebut tidak akan dijalankan meskipun operasi I/O tersebut selesai.
Jika parameter fAlertableTRUE dan salah satu operasi yang tertunda selesai, APC dijalankan dan WSAWaitForMultipleEvents akan mengembalikan WSA_IO_COMPLETION. Peristiwa yang tertunda belum disinyalir. Aplikasi harus memanggil fungsi WSAWaitForMultipleEvents lagi.
Aplikasi yang memerlukan status tunggu yang dapat diperingatkan tanpa menunggu objek peristiwa apa pun disinyalir harus menggunakan fungsi Windows SleepEx .
Implementasi WSAWaitForMultipleEvents saat ini memanggil fungsi WaitForMultipleObjectsEx .
Contoh Kode
Contoh kode berikut menunjukkan cara menggunakan fungsi WSAWaitForMultipleEvents .#ifndef UNICODE
#define UNICODE
#endif
#define WIN32_LEAN_AND_MEAN
#include <winsock2.h>
#include <Ws2tcpip.h>
#include <stdio.h>
// Link with ws2_32.lib
#pragma comment(lib, "Ws2_32.lib")
#define DATA_BUFSIZE 4096
int main()
{
//-----------------------------------------
// Declare and initialize variables
WSADATA wsaData = { 0 };
int iResult = 0;
BOOL bResult = TRUE;
WSABUF DataBuf;
char buffer[DATA_BUFSIZE];
DWORD EventTotal = 0;
DWORD RecvBytes = 0;
DWORD Flags = 0;
DWORD BytesTransferred = 0;
WSAEVENT EventArray[WSA_MAXIMUM_WAIT_EVENTS];
WSAOVERLAPPED AcceptOverlapped;
SOCKET ListenSocket = INVALID_SOCKET;
SOCKET AcceptSocket = INVALID_SOCKET;
DWORD Index;
//-----------------------------------------
// Initialize Winsock
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
wprintf(L"WSAStartup failed: %d\n", iResult);
return 1;
}
//-----------------------------------------
// Create a listening socket bound to a local
// IP address and the port specified
ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (ListenSocket == INVALID_SOCKET) {
wprintf(L"socket failed with error = %d\n", WSAGetLastError());
WSACleanup();
return 1;
}
u_short port = 27015;
char *ip;
sockaddr_in service;
service.sin_family = AF_INET;
service.sin_port = htons(port);
hostent *thisHost;
thisHost = gethostbyname("");
if (thisHost == NULL) {
wprintf(L"gethostbyname failed with error = %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
ip = inet_ntoa(*(struct in_addr *) *thisHost->h_addr_list);
service.sin_addr.s_addr = inet_addr(ip);
//-----------------------------------------
// Bind the listening socket to the local IP address
// and port number
iResult = bind(ListenSocket, (SOCKADDR *) & service, sizeof (SOCKADDR));
if (iResult != 0) {
wprintf(L"bind failed with error = %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
//-----------------------------------------
// Set the socket to listen for incoming
// connection requests
iResult = listen(ListenSocket, 1);
if (iResult != 0) {
wprintf(L"listen failed with error = %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
wprintf(L"Listening...\n");
//-----------------------------------------
// Accept and incoming connection request
AcceptSocket = accept(ListenSocket, NULL, NULL);
if (AcceptSocket == INVALID_SOCKET) {
wprintf(L"accept failed with error = %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
wprintf(L"Client Accepted...\n");
//-----------------------------------------
// Create an event handle and setup an overlapped structure.
EventArray[EventTotal] = WSACreateEvent();
if (EventArray[EventTotal] == WSA_INVALID_EVENT) {
wprintf(L"WSACreateEvent failed with error = %d\n", WSAGetLastError());
closesocket(AcceptSocket);
closesocket(ListenSocket);
WSACleanup();
return 1;
}
ZeroMemory(&AcceptOverlapped, sizeof (WSAOVERLAPPED));
AcceptOverlapped.hEvent = EventArray[EventTotal];
DataBuf.len = DATA_BUFSIZE;
DataBuf.buf = buffer;
EventTotal++;
//-----------------------------------------
// Call WSARecv to receive data into DataBuf on
// the accepted socket in overlapped I/O mode
if (WSARecv(AcceptSocket, &DataBuf, 1, &RecvBytes, &Flags, &AcceptOverlapped, NULL) ==
SOCKET_ERROR) {
iResult = WSAGetLastError();
if (iResult != WSA_IO_PENDING)
wprintf(L"WSARecv failed with error = %d\n", iResult);
}
//-----------------------------------------
// Process overlapped receives on the socket
while (1) {
//-----------------------------------------
// Wait for the overlapped I/O call to complete
Index = WSAWaitForMultipleEvents(EventTotal, EventArray, FALSE, WSA_INFINITE, FALSE);
//-----------------------------------------
// Reset the signaled event
bResult = WSAResetEvent(EventArray[Index - WSA_WAIT_EVENT_0]);
if (bResult == FALSE) {
wprintf(L"WSAResetEvent failed with error = %d\n", WSAGetLastError());
}
//-----------------------------------------
// Determine the status of the overlapped event
bResult =
WSAGetOverlappedResult(AcceptSocket, &AcceptOverlapped, &BytesTransferred, FALSE,
&Flags);
if (bResult == FALSE) {
wprintf(L"WSAGetOverlappedResult failed with error = %d\n", WSAGetLastError());
}
//-----------------------------------------
// If the connection has been closed, close the accepted socket
if (BytesTransferred == 0) {
wprintf(L"Closing accept Socket %d\n", AcceptSocket);
closesocket(ListenSocket);
closesocket(AcceptSocket);
WSACloseEvent(EventArray[Index - WSA_WAIT_EVENT_0]);
WSACleanup();
return 1;
}
//-----------------------------------------
// If data has been received, echo the received data
// from DataBuf back to the client
iResult =
WSASend(AcceptSocket, &DataBuf, 1, &RecvBytes, Flags, &AcceptOverlapped, NULL);
if (iResult != 0) {
wprintf(L"WSASend failed with error = %d\n", WSAGetLastError());
}
//-----------------------------------------
// Reset the changed flags and overlapped structure
Flags = 0;
ZeroMemory(&AcceptOverlapped, sizeof (WSAOVERLAPPED));
AcceptOverlapped.hEvent = EventArray[Index - WSA_WAIT_EVENT_0];
//-----------------------------------------
// Reset the data buffer
DataBuf.len = DATA_BUFSIZE;
DataBuf.buf = buffer;
}
closesocket(ListenSocket);
closesocket(AcceptSocket);
WSACleanup();
return 0;
}
Windows Phone 8: Fungsi ini didukung untuk aplikasi Windows Phone Store di Windows Phone 8 dan yang lebih baru.
Windows 8.1 dan Windows Server 2012 R2: Fungsi ini didukung untuk aplikasi Windows Store di Windows 8.1, Windows Server 2012 R2, dan yang lebih baru.
Persyaratan
Klien minimum yang didukung | Windows 8.1, Windows Vista [aplikasi desktop | Aplikasi UWP] |
Server minimum yang didukung | Windows Server 2003 [aplikasi desktop | Aplikasi UWP] |
Target Platform | Windows |
Header | winsock2.h |
Pustaka | Ws2_32.lib |
DLL | Ws2_32.dll |