Bagikan melalui


Fungsi WSARecv (winsock2.h)

Fungsi WSARecv menerima data dari soket yang terhubung atau soket tanpa koneksi terikat.

Sintaks

int WSAAPI WSARecv(
  [in]      SOCKET                             s,
  [in, out] LPWSABUF                           lpBuffers,
  [in]      DWORD                              dwBufferCount,
  [out]     LPDWORD                            lpNumberOfBytesRecvd,
  [in, out] LPDWORD                            lpFlags,
  [in]      LPWSAOVERLAPPED                    lpOverlapped,
  [in]      LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
);

Parameter

[in] s

Deskriptor yang mengidentifikasi soket yang terhubung.

[in, out] lpBuffers

Penunjuk ke array struktur WSABUF . Setiap struktur WSABUF berisi penunjuk ke buffer dan panjangnya, dalam byte, dari buffer.

[in] dwBufferCount

Jumlah struktur WSABUF dalam array lpBuffers .

[out] lpNumberOfBytesRecvd

Penunjuk ke nomor, dalam byte, data yang diterima oleh panggilan ini jika operasi terima segera selesai.

Gunakan NULL untuk parameter ini jika parameter lpOverlapped bukan NULL untuk menghindari hasil yang berpotensi salah. Parameter ini dapat berupa NULL hanya jika parameter lpOverlapped bukan NULL.

[in, out] lpFlags

Penunjuk ke bendera yang digunakan untuk mengubah perilaku panggilan fungsi WSARecv . Untuk informasi lebih lanjut, lihat bagian Keterangan.

[in] lpOverlapped

Penunjuk ke struktur WSAOVERLAPPED (diabaikan untuk soket yang tidak tumpang tindih).

[in] lpCompletionRoutine

Jenis: LPWSAOVERLAPPED_COMPLETION_ROUTINE _In_opt_

Penunjuk ke rutinitas penyelesaian yang dipanggil ketika operasi terima telah selesai (diabaikan untuk soket yang tidak tumpang tindih).

Nilai kembali

Jika tidak ada kesalahan yang terjadi dan operasi terima telah segera selesai, WSARecv mengembalikan nol. Dalam hal ini, rutinitas penyelesaian telah dijadwalkan untuk dipanggil setelah utas panggilan berada dalam status yang dapat diperingatkan. Jika tidak, nilai SOCKET_ERROR dikembalikan, dan kode kesalahan tertentu dapat diambil dengan memanggil WSAGetLastError. Kode kesalahan WSA_IO_PENDING menunjukkan bahwa operasi yang tumpang tindih telah berhasil dimulai dan penyelesaian tersebut akan ditunjukkan di lain waktu. Kode kesalahan lainnya menunjukkan bahwa operasi yang tumpang tindih tidak berhasil dimulai dan tidak ada indikasi penyelesaian yang akan terjadi.

Kode kesalahan Makna
WSAECONNABORTED
Sirkuit virtual dihentikan karena waktu habis atau kegagalan lainnya.
WSAECONNRESET
Untuk soket aliran, sirkuit virtual direset oleh sisi jarak jauh. Aplikasi harus menutup soket karena tidak lagi dapat digunakan. Untuk soket datagram UDP, kesalahan ini akan menunjukkan bahwa operasi pengiriman sebelumnya menghasilkan pesan ICMP "Port Unreachable".
WSAEDISCON
Soket berorientasi pada pesan dan sirkuit virtual ditutup dengan anggun oleh sisi jarak jauh.
WSAEFAULT
Parameter lpBuffers tidak sepenuhnya terkandung dalam bagian ruang alamat pengguna yang valid.
WSAEINPROGRESS
Panggilan Windows Sockets 1.1 yang diblokir sedang berlangsung, atau penyedia layanan masih memproses fungsi panggilan balik.
WSAEINTR
Panggilan (pemblokiran) dibatalkan oleh fungsi WSACancelBlockingCall .
WSAEINVAL
Soket belum terikat (misalnya, dengan ikatan).
WSAEMSGSIZE
Pesan terlalu besar untuk dimasukkan ke dalam buffer yang ditentukan dan (hanya untuk protokol yang tidak dapat diandalkan) bagian pesan berikutnya yang tidak masuk ke dalam buffer telah dibuang.
WSAENETDOWN
Subsistem jaringan gagal.
WSAENETRESET
Untuk soket berorientasi koneksi, kesalahan ini menunjukkan bahwa koneksi telah terputus karena aktivitas tetap aktif yang mendeteksi kegagalan saat operasi sedang berlangsung. Untuk soket datagram, kesalahan ini menunjukkan bahwa waktu hidup telah kedaluwarsa.
WSAENOTCONN
Soket tidak tersambung.
WSAENOTSOCK
Deskriptor bukan soket.
WSAEOPNOTSUPP
MSG_OOB ditentukan, tetapi soket tidak bergaya aliran seperti jenis SOCK_STREAM, data OOB tidak didukung di domain komunikasi yang terkait dengan soket ini, atau soket tidak langsung dan hanya mendukung operasi pengiriman.
WSAESHUTDOWN
Soket telah dimatikan; tidak dimungkinkan untuk memanggil WSARecv pada soket setelah dipanggil dengan cara diatur ke SD_RECEIVE atau SD_BOTH.
WSAETIMEDOUT
Koneksi terputus karena kegagalan jaringan atau karena sistem serekan gagal merespons.
WSAEWOULDBLOCK

Windows NT: Soket yang tumpang tindih: ada terlalu banyak permintaan I/O yang tumpang tindih. Soket yang tidak tumpang tindih: Soket ditandai sebagai nonblocking dan operasi terima tidak dapat segera diselesaikan.

WSANOTINITIALISED
Panggilan WSAStartup yang berhasil harus terjadi sebelum menggunakan fungsi ini.
WSA_IO_PENDING
Operasi yang tumpang tindih berhasil dimulai dan penyelesaian akan ditunjukkan di lain waktu.
WSA_OPERATION_ABORTED
Operasi yang tumpang tindih telah dibatalkan karena penutupan soket.

Keterangan

Fungsi WSARecv menyediakan beberapa fitur tambahan dibandingkan dengan fungsi recv standar di tiga area penting:

  • Ini dapat digunakan bersama dengan soket yang tumpang tindih untuk melakukan operasi recv yang tumpang tindih.
  • Ini memungkinkan beberapa buffer penerima untuk ditentukan sehingga berlaku untuk jenis I/O yang tersebar/kumpulkan.
  • Parameter lpFlags digunakan baik pada input dan dikembalikan pada output, memungkinkan aplikasi merasakan status output dari bit bendera MSG_PARTIAL . Namun, bit bendera MSG_PARTIAL tidak didukung oleh semua protokol.
Fungsi WSARecv digunakan pada soket yang terhubung atau soket tanpa koneksi terikat yang ditentukan oleh parameter s dan digunakan untuk membaca data masuk. Alamat lokal soket harus diketahui. Untuk aplikasi server, ini biasanya dilakukan secara eksplisit melalui ikatan atau implisit melalui terima atau WSAAccept. Pengikatan eksplisit tidak disarankan untuk aplikasi klien. Untuk aplikasi klien, soket dapat terikat secara implisit ke alamat lokal melalui connect, WSAConnect, sendto, WSASendTo, atau WSAJoinLeaf.

Untuk soket yang tersambung dan tanpa koneksi, fungsi ini membatasi alamat tempat pesan yang diterima diterima. Fungsi ini hanya mengembalikan pesan dari alamat jarak jauh yang ditentukan dalam koneksi. Pesan dari alamat lain (diam-diam) dibuang.

Untuk soket yang tumpang tindih, WSARecv digunakan untuk memposting satu atau beberapa buffer tempat data masuk akan ditempatkan saat tersedia, setelah itu indikasi penyelesaian yang ditentukan aplikasi (pemanggilan rutinitas penyelesaian atau pengaturan objek peristiwa) terjadi. Jika operasi tidak segera selesai, status penyelesaian akhir diambil melalui rutinitas penyelesaian atau WSAGetOverlappedResult.

Catatan Semua I/O yang dimulai oleh utas tertentu dibatalkan ketika utas tersebut keluar. Untuk soket yang tumpang tindih, operasi asinkron yang tertunda dapat gagal jika utas ditutup sebelum operasi selesai. Lihat ExitThread untuk informasi selengkapnya.
 
Jika lpOverlapped dan lpCompletionRoutine adalah NULL, soket dalam fungsi ini akan diperlakukan sebagai soket yang tidak tumpang tindih.

Untuk soket yang tidak tumpang tindih, semantik pemblokiran identik dengan fungsi recv standar dan parameter lpOverlapped dan lpCompletionRoutine diabaikan. Data apa pun yang telah diterima dan di-buffer oleh transportasi akan disalin ke dalam buffer pengguna yang ditentukan. Dalam kasus soket pemblokiran tanpa data yang saat ini telah diterima dan di-buffer oleh transportasi, panggilan akan memblokir hingga data diterima. Windows Sockets 2 tidak menentukan mekanisme batas waktu pemblokiran standar untuk fungsi ini. Untuk protokol yang bertindak sebagai protokol byte-stream, tumpukan mencoba mengembalikan data sebanyak mungkin tergantung pada ruang buffer yang tersedia dan jumlah data yang diterima yang tersedia. Namun, penerimaan satu byte cukup untuk membuka blokir pemanggil. Tidak ada jaminan bahwa lebih dari satu byte akan dikembalikan. Untuk protokol yang bertindak sebagai berorientasi pesan, pesan lengkap diperlukan untuk membuka blokir pemanggil.

Catatan Opsi soket SO_RCVTIMEO dan SO_SNDTIMEO hanya berlaku untuk soket pemblokiran.
 
Apakah protokol bertindak sebagai aliran byte ditentukan oleh pengaturan XP1_MESSAGE_ORIENTED dan XP1_PSEUDO_STREAM dalam struktur WSAPROTOCOL_INFO dan pengaturan bendera MSG_PARTIAL yang diteruskan ke fungsi ini (untuk protokol yang mendukungnya). Tabel berikut mencantumkan kombinasi yang relevan, (tanda bintang (*) menunjukkan bahwa pengaturan bit ini tidak masalah dalam kasus ini).
XP1_MESSAGE_ORIENTED XP1_PSEUDO_STREAM MSG_PARTIAL Bertindak sebagai
tidak diatur * * Aliran byte
* Set * Aliran byte
set Belum diatur set Aliran byte
set Belum diatur tidak diatur Berorientasi pada pesan
 

Buffer diisi dalam urutan di mana buffer muncul dalam array yang ditujukan oleh lpBuffers, dan buffer dikemas sehingga tidak ada lubang yang dibuat.

Jika fungsi ini selesai dengan cara yang tumpang tindih, penyedia layanan Winsock bertanggung jawab untuk menangkap struktur WSABUF sebelum kembali dari panggilan ini. Ini memungkinkan aplikasi untuk membangun array WSABUF berbasis tumpukan yang diacu oleh parameter lpBuffers .

Untuk soket gaya aliran byte (misalnya, ketik SOCK_STREAM), data masuk ditempatkan ke dalam buffer hingga buffer diisi, koneksi ditutup, atau data yang di-buffer secara internal habis. Terlepas dari apakah data yang masuk mengisi semua buffer atau tidak, indikasi penyelesaian terjadi untuk soket yang tumpang tindih.

Untuk soket berorientasi pesan (misalnya, ketik SOCK_DGRAM), pesan masuk ditempatkan ke dalam buffer hingga ukuran total buffer, dan indikasi penyelesaian terjadi untuk soket yang tumpang tindih. Jika pesan lebih besar dari buffer, buffer diisi dengan bagian pertama pesan. Jika fitur MSG_PARTIAL didukung oleh penyedia layanan yang mendasar, bendera MSG_PARTIAL diatur di lpFlags dan operasi penerimaan berikutnya akan mengambil sisa pesan. Jika MSG_PARTIAL tidak didukung tetapi protokolnya dapat diandalkan, WSARecv menghasilkan kesalahan WSAEMSGSIZE dan operasi terima berikutnya dengan buffer yang lebih besar dapat digunakan untuk mengambil seluruh pesan. Jika tidak, (artinya, protokol tidak dapat diandalkan dan tidak mendukung MSG_PARTIAL), data berlebih hilang, dan WSARecv menghasilkan kesalahan WSAEMSGSIZE.

Untuk soket berorientasi koneksi, WSARecv dapat menunjukkan penghentian sirkuit virtual dengan anggun dengan salah satu dari dua cara yang bergantung pada apakah soket berorientasi pada aliran byte atau pesan. Untuk aliran byte, nol byte yang telah dibaca (seperti yang ditunjukkan oleh nilai pengembalian nol untuk menunjukkan keberhasilan, dan nilai lpNumberOfBytesRecvd nol) menunjukkan penutupan dengan anggun dan bahwa tidak ada lagi byte yang akan pernah dibaca. Untuk soket berorientasi pesan, di mana pesan byte nol sering diizinkan, kegagalan dengan kode kesalahan WSAEDISCON digunakan untuk menunjukkan penutupan yang lancar. Dalam hal apa pun kode kesalahan pengembalian WSAECONNRESET menunjukkan penutupan abortif telah terjadi.

Parameter lpFlags dapat digunakan untuk memengaruhi perilaku pemanggilan fungsi di luar opsi yang ditentukan untuk soket terkait. Artinya, semantik fungsi ini ditentukan oleh opsi soket dan parameter lpFlags . Yang terakhir dibangun dengan menggunakan operator bitwise OR dengan salah satu nilai yang tercantum dalam tabel berikut.

Nilai Makna
MSG_PEEK Mengintip data masuk. Data disalin ke dalam buffer, tetapi tidak dihapus dari antrean input.

Bendera ini hanya berlaku untuk soket yang tidak tumpang tindih.

MSG_OOB Memproses data OOB.
MSG_PARTIAL Bendera ini hanya untuk soket berorientasi pesan. Pada output, bendera ini menunjukkan bahwa data yang ditentukan adalah sebagian dari pesan yang dikirimkan oleh pengirim. Bagian pesan yang tersisa akan ditentukan dalam operasi penerimaan berikutnya. Operasi terima berikutnya dengan bendera MSG_PARTIAL dihapus menunjukkan akhir pesan pengirim.

Sebagai parameter input, bendera ini menunjukkan bahwa operasi penerimaan harus selesai meskipun hanya sebagian pesan yang telah diterima oleh penyedia transportasi.

MSG_PUSH_IMMEDIATE Bendera ini hanya untuk soket berorientasi aliran. Bendera ini memungkinkan aplikasi yang menggunakan soket aliran untuk memberi tahu penyedia transportasi untuk tidak menunda penyelesaian permintaan terima tertunda sebagian yang terisi. Ini adalah petunjuk bagi penyedia transportasi bahwa aplikasi bersedia menerima data masuk sesegera mungkin tanpa harus menunggu sisa data yang mungkin masih transit. Apa yang merupakan permintaan terima tertunda yang diisi sebagian adalah masalah khusus transportasi.

Dalam kasus TCP, ini mengacu pada kasus segmen TCP masuk yang ditempatkan ke dalam buffer data permintaan terima di mana tidak ada segmen TCP yang menunjukkan nilai bit PUSH 1. Dalam hal ini, TCP dapat menahan permintaan terima yang diisi sebagian sedikit lebih lama untuk memungkinkan sisa data tiba dengan segmen TCP yang memiliki bit PUSH diatur ke 1. Bendera ini memberi tahu TCP untuk tidak menahan permintaan terima tetapi untuk segera menyelesaikannya.

Menggunakan bendera ini untuk transfer blok besar tidak disarankan karena pemrosesan blok parsial sering kali tidak optimal. Bendera ini hanya berguna untuk kasus di mana menerima dan memproses data parsial segera membantu mengurangi latensi pemrosesan.

Bendera ini adalah petunjuk daripada jaminan aktual.

Bendera ini didukung pada Windows 8.1, Windows Server 2012 R2, dan yang lebih baru.

MSG_WAITALL Permintaan penerimaan hanya akan selesai ketika salah satu peristiwa berikut terjadi:
  • Buffer yang disediakan oleh penelepon benar-benar penuh.
  • Sambungan telah ditutup.
  • Permintaan telah dibatalkan atau terjadi kesalahan.

Ketahuilah bahwa jika penyedia transportasi yang mendasar tidak mendukung MSG_WAITALL, atau jika soket dalam mode non-pemblokiran, maka panggilan ini akan gagal dengan WSAEOPNOTSUPP. Selain itu, jika MSG_WAITALL ditentukan bersama dengan MSG_OOB, MSG_PEEK, atau MSG_PARTIAL, maka panggilan ini akan gagal dengan WSAEOPNOTSUPP.

Bendera ini tidak didukung pada soket datagram atau soket berorientasi pesan.

 

Untuk soket berorientasi pesan, bit MSG_PARTIAL diatur dalam parameter lpFlags jika pesan parsial diterima. Jika pesan lengkap diterima, MSG_PARTIALdibersihkan di lpFlags. Dalam kasus penyelesaian yang tertunda, nilai yang ditunjukkan oleh lpFlags tidak diperbarui. Ketika penyelesaian telah ditunjukkan, aplikasi harus memanggil WSAGetOverlappedResult dan memeriksa bendera yang ditunjukkan oleh parameter lpdwFlags .

Catatan Saat mengeluarkan panggilan Winsock pemblokiran seperti WSARecv dengan parameter lpOverlapped diatur ke NULL, Winsock mungkin perlu menunggu peristiwa jaringan sebelum panggilan dapat selesai. Winsock melakukan penantian yang dapat diperingatkan dalam situasi ini, yang dapat terganggu oleh panggilan prosedur asinkron (APC) yang dijadwalkan pada utas yang sama. Mengeluarkan panggilan Winsock pemblokiran lain di dalam APC yang mengganggu panggilan Winsock pemblokiran yang sedang berlangsung pada utas yang sama akan menyebabkan perilaku yang tidak terdefinisi, dan tidak boleh dicoba oleh klien Winsock.
 

I/O Soket Tumpang Tindih

Jika operasi yang tumpang tindih segera selesai, WSARecv mengembalikan nilai nol dan parameter lpNumberOfBytesRecvd diperbarui dengan jumlah byte yang diterima dan bit bendera yang ditunjukkan oleh parameter lpFlags juga diperbarui. Jika operasi yang tumpang tindih berhasil dimulai dan akan selesai nanti, WSARecv mengembalikan SOCKET_ERROR dan menunjukkan kode kesalahan WSA_IO_PENDING. Dalam hal ini, lpNumberOfBytesRecvd dan lpFlags tidak diperbarui. Ketika operasi yang tumpang tindih selesai, jumlah data yang ditransfer ditunjukkan baik melalui parameter cbTransferred dalam rutinitas penyelesaian (jika ditentukan), atau melalui parameter lpcbTransfer di WSAGetOverlappedResult. Nilai bendera diperoleh dengan memeriksa parameter lpdwFlags dari WSAGetOverlappedResult.

Fungsi WSARecv menggunakan I/O yang tumpang tindih dapat dipanggil dari dalam rutinitas penyelesaian fungsi WSARecv, WSARecvFrom, WSASend , atau WSASendTo sebelumnya. Untuk soket tertentu, rutinitas penyelesaian I/O tidak akan ditumpuk. Ini memungkinkan transmisi data sensitif waktu terjadi sepenuhnya dalam konteks preemptive.

Parameter lpOverlapped harus valid selama durasi operasi yang tumpang tindih. Jika beberapa operasi I/O secara bersamaan luar biasa, masing-masing harus mereferensikan struktur WSAOVERLAPPED terpisah.

Jika parameter lpCompletionRoutine adalah NULL, parameter hEventdari lpOverlapped diberi sinyal ketika operasi yang tumpang tindih selesai jika berisi handel objek peristiwa yang valid. Aplikasi dapat menggunakan WSAWaitForMultipleEvents atau WSAGetOverlappedResult untuk menunggu atau melakukan polling pada objek peristiwa.

Jika lpCompletionRoutine bukan NULL, parameter hEvent diabaikan dan dapat digunakan oleh aplikasi untuk meneruskan informasi konteks ke rutinitas penyelesaian. Penelepon yang melewati lpCompletionRoutinenon-NULL dan kemudian memanggil WSAGetOverlappedResult untuk permintaan I/O yang tumpang tindih yang sama mungkin tidak mengatur parameter fWait untuk pemanggilan WSAGetOverlappedResult ke TRUE. Dalam hal ini penggunaan parameter hEvent tidak terdefinisi, dan mencoba menunggu parameter hEvent akan menghasilkan hasil yang tidak dapat diprediksi.

Rutinitas penyelesaian mengikuti aturan yang sama seperti yang ditetapkan untuk rutinitas penyelesaian I/O file Windows. Rutinitas penyelesaian tidak akan dipanggil sampai utas berada dalam status tunggu yang dapat diperingatkan seperti dapat terjadi ketika fungsi WSAWaitForMultipleEvents dengan parameter fAlertable diatur ke TRUE dipanggil.

Prototipe rutinitas penyelesaian adalah sebagai berikut:


void CALLBACK CompletionROUTINE(
  IN DWORD dwError, 
  IN DWORD cbTransferred, 
  IN LPWSAOVERLAPPED lpOverlapped, 
  IN DWORD dwFlags
);

CompletionRoutine adalah tempat penampung untuk nama fungsi yang ditentukan aplikasi atau yang ditentukan pustaka. dwError menentukan status penyelesaian untuk operasi yang tumpang tindih seperti yang ditunjukkan oleh lpOverlapped. Parameter cbTransferred menentukan jumlah byte yang diterima. Parameter dwFlags berisi informasi yang akan muncul di lpFlags jika operasi penerimaan telah selesai segera. Fungsi ini tidak mengembalikan nilai.

Mengembalikan dari fungsi ini memungkinkan pemanggilan rutinitas penyelesaian lain yang tertunda untuk soket ini. Saat menggunakan WSAWaitForMultipleEvents, semua rutinitas penyelesaian menunggu dipanggil sebelum penantian utas yang dapat diperingatkan terpenuhi dengan kode pengembalian WSA_IO_COMPLETION. Rutinitas penyelesaian dapat dipanggil dalam urutan apa pun, tidak harus dalam urutan yang sama operasi yang tumpang tindih selesai. Namun, buffer yang diposting dijamin akan diisi dalam urutan yang sama di mana buffer ditentukan.

Jika Anda menggunakan port penyelesaian I/O, ketahuilah bahwa urutan panggilan yang dilakukan ke WSARecv juga merupakan urutan di mana buffer diisi. WSARecv tidak boleh dipanggil pada soket yang sama secara bersamaan dari utas yang berbeda, karena dapat mengakibatkan urutan buffer yang tidak dapat diprediksi.

Contoh Kode

Contoh berikut menunjukkan cara menggunakan fungsi WSARecv dalam mode I/O yang tumpang tindih.
#ifndef UNICODE
#define UNICODE
#endif

#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif

#include <Windows.h>

#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#include <stdlib.h>

// Need to link with Ws2_32.lib
#pragma comment(lib, "ws2_32.lib")

#pragma warning(disable: 4127)  // Conditional expression is a constant

#define DATA_BUFSIZE 4096

int __cdecl main(int argc, char **argv)
{
    WSADATA wsd;
    struct addrinfo *result = NULL, *ptr = NULL, hints;
    WSAOVERLAPPED RecvOverlapped;
    SOCKET ConnSocket = INVALID_SOCKET;
    WSABUF DataBuf;
    DWORD RecvBytes, Flags;
    char buffer[DATA_BUFSIZE];

    int err = 0;
    int rc;

    if (argc != 2) {
        wprintf(L"usage: %s server-name\n", argv[0]);
        return 1;
    }
    // Load Winsock
    rc = WSAStartup(MAKEWORD(2, 2), &wsd);
    if (rc != 0) {
        wprintf(L"Unable to load Winsock: %d\n", rc);
        return 1;
    }
    // Make sure the hints struct is zeroed out
    SecureZeroMemory((PVOID) & hints, sizeof (struct addrinfo));

    // Initialize the hints to retrieve the server address for IPv4
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;

    rc = getaddrinfo(argv[1], "27015", &hints, &result);
    if (rc != 0) {
        wprintf(L"getaddrinfo failed with error: %d\n", rc);
        return 1;
    }

    for (ptr = result; ptr != NULL; ptr = ptr->ai_next) {

        ConnSocket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
        if (ConnSocket == INVALID_SOCKET) {
            wprintf(L"socket failed with error: %d\n", WSAGetLastError());
            freeaddrinfo(result);
            return 1;
        }

        rc = connect(ConnSocket, ptr->ai_addr, (int) ptr->ai_addrlen);
        if (rc == SOCKET_ERROR) {

            if (WSAECONNREFUSED == (err = WSAGetLastError())) {
                closesocket(ConnSocket);
                ConnSocket = INVALID_SOCKET;
                continue;
            }
            wprintf(L"connect failed with error: %d\n", err);
            freeaddrinfo(result);
            closesocket(ConnSocket);
            return 1;
        }
        break;
    }
    if (ConnSocket == INVALID_SOCKET) {
        wprintf(L"Unable to establish connection with the server!\n");
        freeaddrinfo(result);
        return 1;
    }

    wprintf(L"Client connected...\n");

    // Make sure the RecvOverlapped struct is zeroed out
    SecureZeroMemory((PVOID) & RecvOverlapped, sizeof (WSAOVERLAPPED));

    // Create an event handle and setup an overlapped structure.
    RecvOverlapped.hEvent = WSACreateEvent();
    if (RecvOverlapped.hEvent == NULL) {
        wprintf(L"WSACreateEvent failed: %d\n", WSAGetLastError());
        freeaddrinfo(result);
        closesocket(ConnSocket);
        return 1;
    }

    DataBuf.len = DATA_BUFSIZE;
    DataBuf.buf = buffer;

    // Call WSARecv until the peer closes the connection
    // or until an error occurs
    while (1) {

        Flags = 0;
        rc = WSARecv(ConnSocket, &DataBuf, 1, &RecvBytes, &Flags, &RecvOverlapped, NULL);
        if ((rc == SOCKET_ERROR) && (WSA_IO_PENDING != (err = WSAGetLastError()))) {
            wprintf(L"WSARecv failed with error: %d\n", err);
            break;
        }

        rc = WSAWaitForMultipleEvents(1, &RecvOverlapped.hEvent, TRUE, INFINITE, TRUE);
        if (rc == WSA_WAIT_FAILED) {
            wprintf(L"WSAWaitForMultipleEvents failed with error: %d\n", WSAGetLastError());
            break;
        }

        rc = WSAGetOverlappedResult(ConnSocket, &RecvOverlapped, &RecvBytes, FALSE, &Flags);
        if (rc == FALSE) {
            wprintf(L"WSARecv operation failed with error: %d\n", WSAGetLastError());
            break;
        }

        wprintf(L"Read %d bytes\n", RecvBytes);

        WSAResetEvent(RecvOverlapped.hEvent);

        // If 0 bytes are received, the connection was closed
        if (RecvBytes == 0)
            break;
    }

    WSACloseEvent(RecvOverlapped.hEvent);
    closesocket(ConnSocket);
    freeaddrinfo(result);

    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

Lihat juga

WSABUF

WSACloseEvent

WSACreateEvent

WSAGetOverlappedResult

WSAOVERLAPPED

WSASocket

WSAWaitForMultipleEvents

Fungsi Winsock

Referensi Winsock

recv