Bagikan melalui


Fungsi panggilan balik LPWSPRECVFROM (ws2spi.h)

Fungsi LPWSPRecvFrom menerima datagram dan menyimpan alamat sumber.

Sintaks

LPWSPRECVFROM Lpwsprecvfrom;

int Lpwsprecvfrom(
  [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,
  \[in\]    LPWSATHREADID lpThreadId,
  [in, out] LPINT lpErrno
)
{...}

Parameter

[in] s

Deskriptor mengidentifikasi soket.

[in, out] lpBuffers

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

[in] dwBufferCount

Jumlah struktur WSABUF dalam array lpBuffers .

[out] lpNumberOfBytesRecvd

Arahkan ke jumlah byte yang diterima oleh panggilan ini.

[in, out] lpFlags

Penunjuk ke bendera.

[out] lpFrom

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

[in, out] lpFromlen

Penunjuk ke ukuran buffer lpFrom , dalam byte, 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 terima telah selesai (diabaikan untuk soket yang tidak tumpang tindih).

\\[in\\] lpThreadId

Penunjuk ke struktur WSATHREADID yang akan digunakan oleh penyedia dalam panggilan berikutnya ke WPUQueueApc. Penyedia harus menyimpan struktur WSATHREADID yang direferensikan (bukan penunjuk ke yang sama) sampai setelah fungsi WPUQueueApc kembali.

[in, out] lpErrno

Arahkan ke kode kesalahan.

Mengembalikan nilai

Jika tidak ada kesalahan yang terjadi dan operasi penerimaan telah selesai segera, LPWSPRecvFrom mengembalikan nol. Perhatikan bahwa dalam hal ini rutinitas penyelesaian, jika ditentukan akan telah diantrekan. Jika tidak, nilai SOCKET_ERROR dikembalikan, dan kode kesalahan tertentu tersedia di lpErrno. 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 tidak ada operasi yang tumpang tindih yang dimulai dan tidak ada indikasi penyelesaian yang akan terjadi.

Kode Kesalahan Makna
WSAENETDOWN
Subsistem jaringan gagal.
WSAEFAULT
Parameter lpFromlen tidak valid: buffer lpFrom terlalu kecil untuk mengakomodasi alamat serekan atau lpbuffers tidak sepenuhnya terkandung dalam bagian ruang alamat pengguna yang valid.
WSAEINTR
(Pemblokiran) panggilan dibatalkan melalui LPWSPCancelBlockingCall.
WSAEINPROGRESS
Pemblokiran panggilan Windows Sockets sedang berlangsung, atau penyedia layanan masih memproses fungsi panggilan balik.
WSAEINVAL
Soket belum terikat (misalnya, dengan LPWSPBind) atau soket tidak dibuat dengan bendera tumpang tindih.
WSAEISCONN
Soket terhubung. Fungsi ini tidak diizinkan dengan soket yang terhubung, baik soket berorientasi koneksi atau tanpa koneksi.
WSAENETRESET
Koneksi telah terputus karena aktivitas tetap aktif mendeteksi kegagalan saat operasi sedang berlangsung.
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 mungkin untuk menjalankan LPWSPRecvFrom pada soket setelah LPWSPShutdown dipanggil dengan cara diatur ke SD_RECEIVE atau SD_BOTH.
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.
WSAEMSGSIZE
Pesan terlalu besar untuk dimasukkan ke dalam buffer yang ditentukan dan (hanya untuk protokol yang tidak dapat diandalkan) bagian berikutnya dari pesan yang tidak masuk ke dalam buffer telah dibuang.
WSAECONNRESET
Sirkuit virtual direset oleh sisi jarak jauh yang mengeksekusi penutupan yang keras atau abortif. Aplikasi harus menutup soket karena tidak lagi dapat digunakan. Pada 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.
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 LPWSPRecvFrom digunakan terutama pada soket tanpa koneksi yang ditentukan oleh s Soket tidak boleh tersambung. Alamat lokal soket harus diketahui. Ini dapat dilakukan secara eksplisit melalui LPWSPBind atau secara implisit melalui LPWSPSendTo atau LPWSPJoinLeaf.

Untuk soket yang tumpang tindih, fungsi ini digunakan untuk memposting satu atau beberapa buffer tempat data masuk akan ditempatkan saat tersedia pada soket (mungkin terhubung), setelah itu indikasi penyelesaian yang ditentukan klien (pemanggilan rutinitas penyelesaian atau pengaturan objek peristiwa) terjadi. Jika operasi tidak segera selesai, status penyelesaian akhir diambil melalui rutinitas penyelesaian atau LPWSPGetOverlappedResult. Perhatikan juga bahwa nilai yang ditunjukkan oleh lpFrom dan lpFromlen tidak diperbarui sampai penyelesaian ditunjukkan. Aplikasi tidak boleh menggunakan atau mengganggu nilai-nilai ini sampai telah diperbarui, oleh karena itu klien tidak boleh menggunakan variabel otomatis (yaitu, berbasis tumpukan) untuk parameter ini.

Jika lpOverlapped dan lpCompletionRoutine null, soket dalam fungsi ini akan diperlakukan sebagai soket yang tidak tumpang tindih.

Untuk soket yang tidak tumpang tindih, parameter lpOverlapped, lpCompletionRoutine, dan lpThreadId diabaikan. Setiap data yang telah diterima dan di-buffer oleh transportasi akan disalin ke dalam buffer pengguna yang disediakan. Untuk kasus soket pemblokiran tanpa data yang saat ini telah diterima dan di-buffer oleh transportasi, panggilan akan memblokir hingga data diterima sesuai dengan semantik pemblokiran yang ditetapkan untuk LPWSPRecv.

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

Array struktur WSABUF yang diacu oleh parameter lpBuffers bersifat sementara. Jika operasi ini selesai dengan cara yang tumpang tindih, penyedia layanan bertanggung jawab untuk menangkap array pointer ini ke struktur WSABUF sebelum kembali dari panggilan ini. Ini memungkinkan klien Windows Sockets SPI untuk membangun array WSABUF berbasis tumpukan.

Untuk jenis soket tanpa koneksi, alamat asal data disalin ke buffer yang ditunjukkan oleh lpFrom. Pada input, 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 disebutkan 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 klien Windows Sockets SPI. Parameter lpFrom dan lpFromlen diabaikan untuk soket berorientasi koneksi.

Untuk soket gaya aliran byte (misalnya, jenis SOCK_STREAM), data masuk ditempatkan ke dalam buffer hingga buffer terisi, 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, satu pesan masuk ditempatkan ke dalam buffer yang disediakan, hingga ukuran total buffer yang disediakan, dan indikasi penyelesaian terjadi untuk soket yang tumpang tindih. Jika pesan lebih besar dari buffer yang disediakan, buffer diisi dengan bagian pertama pesan. Jika fitur MSG_PARTIAL didukung oleh penyedia layanan, bendera MSG_PARTIAL diatur dalam lpFlags untuk soket dan operasi penerimaan berikutnya akan mengambil sisa pesan. Jika MSG_PARTIAL tidak didukung tetapi protokolnya dapat diandalkan, LPWSPRecvFrom 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 LPWSPRecvFrom 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 bitwise OR dengan salah satu nilai 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 Out of Band (OOB).
MSG_PARTIAL Bendera ini hanya untuk soket berorientasi pesan. Pada output, menunjukkan bahwa data yang disediakan adalah bagian dari pesan yang dikirimkan oleh pengirim. Bagian pesan yang tersisa akan disediakan dalam operasi penerimaan berikutnya. Operasi penerimaan berikutnya dengan bendera MSG_PARTIAL dihapus menunjukkan akhir pesan pengirim. Sebagai parameter input, MSG_PARTIAL 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_PARTIAL dibersihkan di lpFlags. Dalam kasus penyelesaian tertunda, nilai yang ditunjukkan oleh lpFlags tidak diperbarui. Ketika penyelesaian telah ditunjukkan klien Windows Sockets SPI harus memanggil LPWSPGetOverlappedResult dan memeriksa bendera yang ditunjukkan oleh parameter lpdwFlags .

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

Penyedia harus mengizinkan fungsi ini dipanggil dari dalam rutinitas penyelesaian fungsi LPWSPRecv, LPWSPRecvFrom, LPWSPSend, atau LPWSPSendTo sebelumnya. Namun, untuk soket tertentu, rutinitas penyelesaian I/O tidak dapat 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 tumpang tindih terpisah. Struktur WSAOverlapped didefinisikan di halaman referensinya sendiri.

Jika parameter lpCompletionRoutine null, penyedia layanan memberi sinyal kepada anggota hEventdari lpOverlapped ketika operasi yang tumpang tindih selesai jika berisi handel objek peristiwa yang valid. Klien Windows Sockets SPI dapat menggunakan LPWSPGetOverlappedResult untuk menunggu atau melakukan polling pada objek peristiwa.

Jika lpCompletionRoutine tidak null, anggota hEvent diabaikan dan dapat digunakan oleh klien Windows Sockets SPI untuk meneruskan informasi konteks ke rutinitas penyelesaian. Penyedia layanan bertanggung jawab untuk mengatur pemanggilan rutinitas klien yang ditentukan–penyelesaian ketika operasi yang tumpang tindih selesai. Karena rutinitas penyelesaian harus dijalankan dalam konteks utas yang sama yang memulai operasi yang tumpang tindih, itu tidak dapat dipanggil langsung dari penyedia layanan. Ws2_32.dll menawarkan mekanisme panggilan prosedur asinkron (APC) untuk memfasilitasi pemanggilan rutinitas penyelesaian.

Penyedia layanan mengatur agar fungsi dijalankan dalam rangkaian dan konteks proses yang tepat dengan memanggil WPUQueueApc. Fungsi ini dapat dipanggil dari proses dan konteks utas apa pun, bahkan konteks yang berbeda dari utas dan proses yang digunakan untuk memulai operasi yang tumpang tindih.

WPUQueueApc mengambil parameter input penunjuk ke struktur WSATHREADID (diberikan kepada penyedia melalui parameter input lpThreadId ), penunjuk ke fungsi APC yang akan dipanggil, dan nilai konteks yang kemudian diteruskan ke fungsi APC. Karena hanya satu nilai konteks yang tersedia, fungsi APC itu sendiri tidak dapat menjadi rutinitas penyelesaian yang ditentukan klien. Penyedia layanan harus menyediakan pointer ke fungsi APC sendiri yang menggunakan nilai konteks yang disediakan untuk mengakses informasi hasil yang diperlukan untuk operasi yang tumpang tindih, lalu memanggil rutinitas penyelesaian yang ditentukan klien.

Prototipe untuk rutinitas penyelesaian yang disediakan klien 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 disediakan klien. dwError menentukan status penyelesaian untuk operasi yang tumpang tindih seperti yang ditunjukkan oleh lpOverlapped. cbTransferred menentukan jumlah byte yang diterima. dwFlags berisi informasi yang akan muncul di lpFlags jika operasi penerimaan telah selesai segera. Fungsi ini tidak mengembalikan nilai.

Rutinitas penyelesaian dapat dipanggil dalam urutan apa pun, meskipun belum tentu dalam urutan yang sama bahwa operasi yang tumpang tindih selesai. Namun, buffer yang diposting dijamin akan diisi dalam urutan yang sama dengan yang disediakan.

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.

Persyaratan

   
Klien minimum yang didukung Windows 2000 Professional [hanya aplikasi desktop]
Server minimum yang didukung Windows 2000 Server [hanya aplikasi desktop]
Header ws2spi.h

Lihat juga

WPUQueueApc

LPWSPGetOverlappedResult

LPWSPSocket