Fungsi WSARecvFrom (winsock2.h)

Fungsi WSARecvFrom menerima datagram dan menyimpan alamat sumber.

Sintaks

int WSAAPI WSARecvFrom(
  [in]      SOCKET                             s,
  [in, out] LPWSABUF                           lpBuffers,
  [in]      DWORD                              dwBufferCount,
  [out]     LPDWORD                            lpNumberOfBytesRecvd,
  [in, out] LPDWORD                            lpFlags,
  [out]     sockaddr                           *lpFrom,
  [in, out] LPINT                              lpFromlen,
  [in]      LPWSAOVERLAPPED                    lpOverlapped,
  [in]      LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
);

Parameter

[in] s

Deskriptor yang mengidentifikasi soket.

[in, out] lpBuffers

Penunjuk ke array struktur WSABUF . Setiap struktur WSABUF berisi pointer ke buffer dan panjang buffer.

[in] dwBufferCount

Jumlah struktur WSABUF dalam array lpBuffers .

[out] lpNumberOfBytesRecvd

Penunjuk ke jumlah byte yang diterima oleh panggilan ini jika operasi WSARecvFrom 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

Pointer ke bendera yang digunakan untuk memodifikasi perilaku panggilan fungsi WSARecvFrom . Lihat keterangan di bawah ini.

[out] lpFrom

Penunjuk opsional ke buffer yang akan menyimpan alamat sumber setelah menyelesaikan operasi yang tumpang tindih.

[in, out] lpFromlen

Penunjuk ke ukuran, dalam byte, dari buffer "dari" yang diperlukan hanya jika lpFrom ditentukan.

[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 WSARecvFrom telah selesai (diabaikan untuk soket yang tidak tumpang tindih).

Nilai kembali

Jika tidak ada kesalahan yang terjadi dan operasi terima telah segera selesai, WSARecvFrom 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
WSAECONNRESET
Sirkuit virtual direset oleh sisi jarak jauh yang mengeksekusi penutupan yang keras atau abortif. Aplikasi harus menutup soket karena tidak lagi dapat digunakan. Untuk soket datagram UPD, kesalahan ini akan menunjukkan bahwa operasi pengiriman sebelumnya menghasilkan pesan "Port Tidak Dapat Dijangkau" ICMP.
WSAEFAULT
Parameter lpBuffers, lpFlags, lpFrom, lpNumberOfBytesRecvd, lpFromlen, lpOverlapped, atau lpCompletionRoutine tidak sepenuhnya terkandung dalam bagian ruang alamat pengguna yang valid: buffer lpFrom terlalu kecil untuk mengakomodasi alamat serekan.
WSAEINPROGRESS
Panggilan Windows Sockets 1.1 yang diblokir sedang berlangsung, atau penyedia layanan masih memproses fungsi panggilan balik.
WSAEINTR
Panggilan Windows Socket 1.1 pemblokiran dibatalkan melalui WSACancelBlockingCall.
WSAEINVAL
Soket belum terikat (dengan ikatan, misalnya).
WSAEMSGSIZE
Pesan terlalu besar untuk 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 datagram, kesalahan ini menunjukkan bahwa waktu hidup telah kedaluwarsa.
WSAENOTCONN
Soket tidak tersambung (hanya soket berorientasi koneksi).
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 tumpang tindih berhasil dimulai dan penyelesaian akan ditunjukkan nanti.
WSA_OPERATION_ABORTED
Operasi yang tumpang tindih telah dibatalkan karena penutupan soket.

Keterangan

Fungsi WSARecvFrom menyediakan fungsionalitas di atas dan di atas fungsi recvfrom standar di tiga area penting:

  • Ini dapat digunakan bersama dengan soket yang tumpang tindih untuk melakukan operasi penerimaan yang tumpang tindih.
  • Ini memungkinkan beberapa buffer penerima untuk ditentukan sehingga berlaku untuk jenis I/O yang tersebar/kumpulkan.
  • Parameter lpFlags adalah parameter input dan output, memungkinkan aplikasi merasakan status output dari bit bendera MSG_PARTIAL . Ketahuilah bahwa bit bendera MSG_PARTIAL tidak didukung oleh semua protokol.
Fungsi WSARecvFrom digunakan terutama pada soket tanpa koneksi yang ditentukan oleh s. Alamat lokal soket harus diketahui. Untuk aplikasi server, ini biasanya dilakukan secara eksplisit melalui ikatan. Pengikatan eksplisit tidak disarankan untuk aplikasi klien. Untuk aplikasi klien yang menggunakan fungsi ini, soket dapat terikat secara implisit ke alamat lokal melalui sendto, WSASendTo, atau WSAJoinLeaf.

Untuk soket yang tumpang tindih, fungsi ini digunakan untuk memposting satu atau beberapa buffer di mana data masuk akan ditempatkan saat tersedia pada soket (mungkin terhubung), 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. Selain itu, nilai yang ditunjukkan oleh lpFrom dan lpFromlen tidak diperbarui sampai penyelesaian itu sendiri ditunjukkan. Aplikasi tidak boleh menggunakan atau mengganggu nilai-nilai ini sampai telah diperbarui; oleh karena itu aplikasi tidak boleh menggunakan variabel otomatis (yaitu, berbasis tumpukan) untuk parameter ini.

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 WSARecv standar dan parameter lpOverlapped dan lpCompletionRoutine diabaikan. Data apa pun yang telah diterima dan di-buffer oleh transportasi akan disalin ke dalam buffer pengguna. Untuk kasus soket pemblokiran tanpa data yang saat ini telah diterima dan di-buffer oleh transportasi, panggilan akan memblokir hingga data diterima.

Buffer diisi dalam urutan di mana buffer muncul dalam array yang ditunjukkan 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 jenis soket tanpa koneksi, alamat asal data disalin ke buffer yang ditunjukkan oleh lpFrom. Nilai yang ditunjukkan oleh lpFromlen diinisialisasi ke ukuran buffer ini, dan dimodifikasi pada penyelesaian untuk menunjukkan ukuran sebenarnya dari alamat yang disimpan di sana. Seperti yang dinyatakan sebelumnya untuk soket yang tumpang tindih, parameter lpFrom dan lpFromlen tidak diperbarui sampai setelah I/O yang tumpang tindih selesai. Memori yang ditujukan oleh parameter ini harus, oleh karena itu, tetap tersedia untuk penyedia layanan dan tidak dapat dialokasikan pada bingkai tumpukan aplikasi. Parameter lpFrom dan lpFromlen diabaikan untuk soket berorientasi koneksi.

Untuk soket gaya aliran byte (misalnya, ketik SOCK_STREAM), data masuk ditempatkan ke dalam buffer hingga:

  • Buffer diisi.
  • Sambungan ditutup.
  • 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, 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, WSARecvFrom 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 WSARecvFrom menghasilkan kesalahan WSAEMSGSIZE.

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 OR bitwise dengan salah satu nilai yang tercantum dalam tabel berikut.

Nilai Makna
MSG_PEEK Mempratinjau 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 adalah bagian dari pesan yang dikirimkan oleh pengirim. Bagian pesan yang tersisa akan dikirimkan 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 layanan.

 

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 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 WSARecvFrom 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, WSARecvFrom 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, WSARecvFrom mengembalikan SOCKET_ERROR dan menunjukkan kode kesalahan WSA_IO_PENDING. Dalam hal ini, lpNumberOfBytesRecvd dan lpFlags tidak diperbarui. Ketika operasi yang tumpang tindih menyelesaikan jumlah data yang ditransfer ditunjukkan baik melalui parameter cbTransferred dalam rutinitas penyelesaian (jika ditentukan), atau melalui parameter lpcbTransfer di WSAGetOverlappedResult. Nilai bendera diperoleh baik melalui parameter dwFlags dari rutinitas penyelesaian, atau dengan memeriksa parameter lpdwFlagsWSAGetOverlappedResult.

Fungsi WSARecvFrom 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 lpCompletionRoutineadalah 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.

Jika port penyelesaian IO digunakan dan parameter lpCompletionRoutine dan parameter hEventadalah NULL, hasil operasi adalah jadwal pada port penyelesaian IO. Ini terjadi untuk semua operasi yang berhasil, apakah operasi segera selesai atau tidak.

Penyedia transportasi memungkinkan aplikasi untuk memanggil operasi kirim dan terima dari dalam konteks rutinitas penyelesaian I/O soket, dan menjamin bahwa, untuk soket tertentu, rutinitas penyelesaian I/O tidak akan bersarang. Ini memungkinkan transmisi data sensitif waktu terjadi sepenuhnya dalam konteks preemptive.

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. 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 dipenuhi 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 dengan yang ditentukan.

Contoh Kode

Contoh berikut menunjukkan penggunaan fungsi WSARecvFrom .
#ifndef UNICODE
#define UNICODE
#endif

#define WIN32_LEAN_AND_MEAN

#include <winsock2.h>
#include <Ws2tcpip.h>
#include <stdio.h>

int __cdecl main()
{

    WSADATA wsaData;
    WSABUF DataBuf;
    WSAOVERLAPPED Overlapped;

    SOCKET RecvSocket = INVALID_SOCKET;
    struct sockaddr_in RecvAddr;
    struct sockaddr_in SenderAddr;

    int SenderAddrSize = sizeof (SenderAddr);
    u_short Port = 27015;

    char RecvBuf[1024];
    int BufLen = 1024;
    DWORD BytesRecv = 0;
    DWORD Flags = 0;

    int err = 0;
    int rc;
    int retval = 0;
    
    //-----------------------------------------------
    // Initialize Winsock
    rc = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (rc != 0) {
        /* Could not find a usable Winsock DLL */
        wprintf(L"WSAStartup failed with error: %ld\n", rc);
        return 1;
    }

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

    // Create an event handle and setup the overlapped structure.
    Overlapped.hEvent = WSACreateEvent();
    if (Overlapped.hEvent == NULL) {
        wprintf(L"WSACreateEvent failed with error: %d\n", WSAGetLastError());
        WSACleanup();
        return 1;
    }
    //-----------------------------------------------
    // Create a receiver socket to receive datagrams
    RecvSocket = WSASocket(AF_INET,
                           SOCK_DGRAM,
                           IPPROTO_UDP, NULL, 0, WSA_FLAG_OVERLAPPED);

    if (RecvSocket == INVALID_SOCKET) {
        /* Could not open a socket */
        wprintf(L"WSASocket failed with error: %ld\n", WSAGetLastError());
        WSACloseEvent(Overlapped.hEvent);
        WSACleanup();
        return 1;
    }
    //-----------------------------------------------
    // Bind the socket to any address and the specified port.
    RecvAddr.sin_family = AF_INET;
    RecvAddr.sin_port = htons(Port);
    RecvAddr.sin_addr.s_addr = htonl(INADDR_ANY);

    rc = bind(RecvSocket, (SOCKADDR *) & RecvAddr, sizeof (RecvAddr));
    if (rc != 0) {
        /* Bind to the socket failed */
        wprintf(L"bind failed with error: %ld\n", WSAGetLastError());
        WSACloseEvent(Overlapped.hEvent);
        closesocket(RecvSocket);
        WSACleanup();
        return 1;
    }

    //-----------------------------------------------
    // Call the recvfrom function to receive datagrams
    // on the bound socket.
    DataBuf.len = BufLen;
    DataBuf.buf = RecvBuf;
    wprintf(L"Listening for incoming datagrams on port=%d\n", Port);
    rc = WSARecvFrom(RecvSocket,
                      &DataBuf,
                      1,
                      &BytesRecv,
                      &Flags,
                      (SOCKADDR *) & SenderAddr,
                      &SenderAddrSize, &Overlapped, NULL);

    if (rc != 0) {
        err = WSAGetLastError();
        if (err != WSA_IO_PENDING) {
            wprintf(L"WSARecvFrom failed with error: %ld\n", err);
            WSACloseEvent(Overlapped.hEvent);
            closesocket(RecvSocket);
            WSACleanup();
            return 1;
        }
        else {
            rc = WSAWaitForMultipleEvents(1, &Overlapped.hEvent, TRUE, INFINITE, TRUE);
            if (rc == WSA_WAIT_FAILED) {
                wprintf(L"WSAWaitForMultipleEvents failed with error: %d\n", WSAGetLastError());
                retval = 1;
            }

            rc = WSAGetOverlappedResult(RecvSocket, &Overlapped, &BytesRecv,
                                FALSE, &Flags);
            if (rc == FALSE) {
                wprintf(L"WSArecvFrom failed with error: %d\n", WSAGetLastError());
                retval = 1;
            }
            else
                wprintf(L"Number of received bytes = %d\n", BytesRecv);
                
            wprintf(L"Finished receiving. Closing socket.\n");
        }
        
    }
    //---------------------------------------------
    // When the application is finished receiving, close the socket.

    WSACloseEvent(Overlapped.hEvent);
    closesocket(RecvSocket);
    wprintf(L"Exiting.\n");

    //---------------------------------------------
    // Clean up and quit.
    WSACleanup();
    return (retval);
}

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

WSASend

WSASendTo

WSASocket

WSAWaitForMultipleEvents

Fungsi Winsock

Referensi Winsock

kirim ke