Bagikan melalui


Pengembangan Server Menggunakan Handel Konteks

Dari perspektif pengembangan program server, handel konteks adalah penunjuk yang tidak ditiru. Program server menginisialisasi handel konteks dengan mengarahkannya ke data dalam memori atau pada beberapa bentuk penyimpanan lain (seperti file pada disk).

Misalnya, klien menggunakan handel konteks untuk meminta serangkaian pembaruan pada rekaman dalam database. Klien memanggil prosedur jarak jauh di server dan meneruskannya kunci pencarian. Program server mencari database untuk kunci pencarian dan mendapatkan nomor rekaman bilangan bulat dari rekaman yang cocok. Server kemudian dapat mengarahkan pointer untuk membatalkan di lokasi memori yang berisi nomor rekaman. Ketika kembali, prosedur jarak jauh harus mengembalikan penunjuk sebagai handel konteks melalui nilai yang dikembalikan atau daftar parameternya. Klien harus meneruskan penunjuk ke server setiap kali disebut prosedur jarak jauh untuk memperbarui catatan. Selama setiap operasi pembaruan ini, server akan mentransmisikan penunjuk kekosongan untuk menjadi pointer ke bilangan bulat.

Setelah program server menunjuk handel konteks pada data konteks, handel dianggap dibuka. Handel yang berisi nilai NULL ditutup. Server mempertahankan handel konteks yang dibuka hingga klien memanggil prosedur jarak jauh yang menutupnya. Jika sesi klien berakhir saat handel terbuka, run time RPC memanggil rutinitas run-down server untuk membebaskan handel.

Fragmen kode berikut menunjukkan bagaimana server mungkin menerapkan handel konteks. Dalam contoh ini, server mempertahankan file data yang ditulis klien menggunakan prosedur jarak jauh. Informasi konteks adalah handel file yang melacak lokasi saat ini dalam file tempat server akan menulis data. Handel file dipaketkan sebagai handel konteks dalam daftar parameter untuk panggilan prosedur jarak jauh. Struktur berisi nama file dan handel file. Definisi antarmuka untuk contoh ini ditampilkan dalam Pengembangan Antarmuka Menggunakan Handel Konteks.

/* cxhndlp.c (fragment of file containing remote procedures) */
typedef struct 
{
     FILE* hFile;
     char   achFile[256];
} FILE_CONTEXT_TYPE;

Fungsi RemoteOpen membuka file di server:

short RemoteOpen(
    PPCONTEXT_HANDLE_TYPE pphContext,
    unsigned char *pszFileName)
{
    FILE               *hFile;
    FILE_CONTEXT_TYPE  *pFileContext;
 
    if ((hFile = fopen(pszFileName, "r")) == NULL) 
    {
        *pphContext = (PCONTEXT_HANDLE_TYPE) NULL;
        return(-1);
    }
    else 
    {
        pFileContext = (FILE_CONTEXT_TYPE *) 
                       MIDL_user_allocate(sizeof(FILE_CONTEXT_TYPE));
        pFileContext->hFile = hFile;
        // check if pszFileName is longer than 256 and if yes, return
        // an error
        strcpy_s(pFileContext->achFile, srlen(pszFileName), pszFileName);
        *pphContext = (PCONTEXT_HANDLE_TYPE) pFileContext;
        return(0);
    }
}

Fungsi RemoteRead membaca file di server.

short RemoteRead(
    PCONTEXT_HANDLE_TYPE phContext, 
    unsigned char *pbBuf, 
    short *pcbBuf) 
{ 
    FILE_CONTEXT_TYPE *pFileContext; 
    printf("in RemoteRead\n"); 
    pFileContext = (FILE_CONTEXT_TYPE *) phContext; 
    *pcbBuf = (short) fread(pbBuf, sizeof(char), 
                            BUFSIZE, 
                            pFileContext->hFile); 
    return(*pcbBuf); 
}

Fungsi RemoteClose menutup file pada server. Perhatikan bahwa aplikasi server harus menetapkan NULL ke handel konteks sebagai bagian dari fungsi tutup. Ini berkomunikasi ke stub server dan pustaka run-time RPC yang ditangani konteks telah dihapus. Jika tidak, koneksi akan tetap terbuka dan akhirnya run-down konteks akan terjadi.

void RemoteClose(PPCONTEXT_HANDLE_TYPE pphContext)
{
    FILE_CONTEXT_TYPE *pFileContext;
 
    if (*pphContext == NULL)
    {
        //Log error, client tried to close a NULL handle.
        return;
    }
    pFileContext = (FILE_CONTEXT_TYPE *)*pphContext;
    printf("File %s closed.\n", pFileContext->achFile);
    fclose(pFileConext->hFile);
    MIDL_user_free(pFileContext);
 
    // This tells the run-time, when it is marshalling the out 
    // parameters, that the context handle has been closed normally.
    *pphContext = NULL;
}

Catatan

Meskipun diharapkan klien meneruskan handel konteks yang valid ke panggilan dengan atribut arah [in, out], RPC tidak menolak handel konteks NULL untuk kombinasi atribut arah ini. Handel konteks NULL diteruskan ke server sebagai penunjuk NULL . Kode server untuk panggilan yang berisi handel konteks [in, out] harus ditulis untuk menghindari pelanggaran akses saat pointer NULL diterima.