Mengirim dan Menerima Data PGM

Mengirim dan menerima data PGM mirip dengan mengirim atau menerima data pada soket apa pun. Ada pertimbangan khusus untuk PGM, yang diuraikan dalam paragraf berikut.

Mengirim Data PGM

Setelah sesi pengirim PGM dibuat, data dikirim menggunakan berbagai fungsi pengiriman Soket Windows: kirim, kirim ke, WSASend, dan WSASendTo. Karena handel Windows Sockets adalah handel sistem file, fungsi lain seperti fungsi WriteFile dan CRT juga dapat mengirimkan data. Cuplikan kode berikut mengilustrasikan operasi pengirim PGM:

LONG        error;
    //:
error = send (s, pSendBuffer, SendLength, 0);
if (error == SOCKET_ERROR)
{
    fprintf (stderr, "send() failed: Error = %d\n",
             WSAGetLastError());
}

Saat menggunakan mode pesan (SOCK_RDM), setiap panggilan ke fungsi kirim menghasilkan pesan diskrit, yang terkadang tidak diinginkan; aplikasi mungkin ingin mengirim pesan 2 megabyte dengan beberapa panggilan untuk dikirim. Dalam keadaan seperti itu, pengirim dapat mengatur opsi soket RM_SET_MESSAGE_BOUNDARY untuk menunjukkan ukuran pesan yang mengikuti.

Jika jendela kirim penuh, kirim baru dari aplikasi tidak diterima sampai jendela telah dimajukan. Mencoba mengirim soket non-pemblokiran gagal dengan WSAEWOULDBLOCK; soket pemblokiran hanya memblokir sampai jendela maju ke titik di mana data yang diminta dapat di-buffer dan dikirim. Dalam I/O yang tumpang tindih, operasi tidak selesai sampai jendela cukup maju untuk mengakomodasi data baru.

Menerima Data PGM

Setelah sesi penerima PGM dibuat, data diterima menggunakan berbagai fungsi penerima Windows Sockets: recv, recvfrom, WSARecv, dan WSARecvFrom. Karena handel Windows Sockets juga merupakan handel file, fungsi ReadFile dan CRT juga dapat digunakan untuk menerima data sesi PGM. Transportasi meneruskan data ke penerima saat tiba selama data berurutan. Transportasi menjamin bahwa data yang dikembalikan berdamai dan bebas dari duplikat. Cuplikan kode berikut mengilustrasikan operasi penerimaan PGM:

LONG        BytesRead;
    //:
BytesRead = recv (sockR, pTestBuffer, MaxBufferSize, 0);
if (BytesRead == 0)
{
    fprintf(stdout, "Session was terminated\n");
}
else if (BytesRead == SOCKET_ERROR)
{
    fprintf(stderr, "recv() failed: Error = %d\n",
            WSAGetLastError());
}

Saat menggunakan mode pesan (SOCK_RDM), transportasi menunjukkan kapan pesan parsial diterima, baik dengan kesalahan WSAEMSGSIZE, atau dengan mengatur bendera MSG_PARTIAL saat kembali dari fungsi WSARecv dan WSARecvFrom . Ketika fragmen terakhir dari pesan lengkap dikembalikan ke klien, kesalahan atau bendera tidak ditunjukkan.

Ketika sesi dihentikan dengan baik, operasi terima gagal dengan WSAEDISCON. Ketika kehilangan data terjadi di transportasi, PGM untuk sementara buffer paket yang tidak berurutan dan mencoba memulihkan data yang hilang. Jika kehilangan data tidak dapat dipulihkan, operasi terima gagal dengan WSAECONNRESET, dan sesi dihentikan. Sesi dapat direset karena berbagai kondisi, termasuk yang berikut:

  • Penerima atau tingkat koneksi masuk terlalu lambat untuk mengimbangi laju data masuk.
  • Kehilangan data yang berlebihan terjadi, mungkin karena kondisi jaringan sementara, seperti masalah perutean, ketidakstabilan jaringan, dan sebagainya.
  • Terjadi kesalahan yang tidak dapat dipulihkan pada pengirim.
  • Pemanfaatan sumber daya yang berlebihan terjadi pada komputer lokal, seperti melebihi penyimpanan buffer internal maksimum yang diizinkan, atau mengalami kondisi di luar sumber daya.
  • Terjadi kesalahan pemeriksaan konsistensi data.
  • Kegagalan dalam komponen PGM bergantung pada, seperti TCP/IP atau Windows Sockets.

Item pertama dan kedua dalam daftar di atas dapat mengakibatkan penerima melakukan buffering yang berlebihan sebelum kehabisan sumber daya, atau sebelum akhirnya bergerak melampaui jendela pengirim.

Mengakhiri sesi PGM

Pengirim atau penerima PGM dapat berhenti mengirim atau menerima data dengan memanggil closesocket. Penerima harus memanggil closesocket pada soket mendengarkan dan menerima untuk mencegah menangani kebocoran. Memanggil matikan pada pengirim sebelum memanggil closesocket memastikan semua data terkirim, dan memastikan data perbaikan dipertahankan sampai jendela kirim maju melewati urutan data terakhir, bahkan jika aplikasi itu sendiri berakhir.