共用方式為


在客戶端上實作輸出管道

使用輸出管道將資料從伺服器傳送至用戶端時,您必須在用戶端中實作推播程式。 推送程序會從用戶端存根取得緩衝區指標和元素計數,如果元素計數大於0,則會進行數據處理。 例如,它可以將數據從存根的緩衝區複製到自己的記憶體。 或者,它可以處理存根緩衝區中的數據,並將其儲存至檔案。 當項目計數等於零時,推送程式會在傳回之前完成任何必要的清除工作。

在下列範例中,用戶端函式 ReceiveLongs 會配置管道結構和全域記憶體緩衝區。 它會初始化 結構、進行遠端過程調用,然後釋放記憶體。

//file: client.c (fragment)
#include <windows.h>
#include "pipedemo.h"
long *  globalPipeData;
long    globalBuffer[BUF_SIZE];
 
ulong   pipeDataIndex; /* state variable */
 
void ReceiveLongs()
{
    LONG_PIPE *outputPipe;
    idl_long_int i;
 
    globalPipeData =
        (long *)malloc( sizeof(long) * PIPE_SIZE );
    
    pipeDataIndex = 0;
    outputPipe.state =  (rpc_ss_pipe_state_t )&pipeDataIndex;
    outputPipe.push  = PipePush;
    outputPipe.alloc = PipeAlloc;
 
    OutPipe( &outputPipe ); /* Make the rpc */
 
    free( (void *)globalPipeData );
 
}//end ReceiveLongs()

void PipeAlloc( rpc_ss_pipe_state_t stateInfo,
                ulong requestedSize,
                long **allocatedBuffer,
                ulong *allocatedSize )
{ 
    ulong *state = (ulong *)stateInfo;
    if ( requestedSize > (BUF_SIZE*sizeof(long)) )
    {
       *allocatedSize = BUF_SIZE * sizeof(long);
    }
    else
    {
       *allocatedSize = requestedSize;
    }
    *allocatedBuffer = globalBuffer; 
} //end PipeAlloc
 
void PipePush( rpc_ss_pipe_state_t stateInfo,
               long *buffer,
               ulong numberOfElements )
{
    ulong elementsToCopy, i;
    ulong *state = (ulong *)stateInfo;

    if (numberOfElements == 0)/* end of data */
    {
        *state = 0; /* Reset the state = global index */
    }
    else
    {
        if (*state + numberOfElements > PIPE_SIZE)
            elementsToCopy = PIPE_SIZE - *state;
        else
            elementsToCopy = numberOfElements;
 
        for (i=0; i <elementsToCopy; i++)
        { 
            /*client receives data */
            globalPipeData[*state] = buffer[i];
            (*state)++;
        }
    }
}//end PipePush

此範例包含 MIDL 編譯程式所產生的頭檔。 如需詳細資訊,請參閱 在 IDL 檔案中定義管道。 它還會宣告一個變數 globalPipeData,並將其用作數據接收器。 變數 globalBuffer 是一個緩衝區,推送程式會用來接收儲存在 globalPipeData 中的數據區塊。

ReceiveLongs 函式會宣告管道,並配置全域數據接收變數的記憶體空間。 在您的用戶端/伺服器程式中,數據接收可以是用戶端所建立的檔案或數據結構。 在此簡單範例中,數據源是長整數的動態配置緩衝區。

在數據傳輸開始之前,您的用戶端程式必須初始化輸出管道結構。 它必須設定狀態變數、推送程式和配置程式的指標。 在此範例中,輸出管道變數稱為 outputPipe。

用戶端會透過叫用伺服器上的遠端程式來發出伺服器訊號,表示他們已準備好接收數據。 在此範例中,遠端程式稱為 OutPipe。 當用戶端呼叫遠端程式時,伺服器會開始數據傳輸。 每次資料送達時,用戶端的 stub 都會視需要呼叫用戶端的分配和推送的程式。

此範例中,分配程序不會在每次需要使用緩衝區時配置記憶體,而僅設定變數 globalBuffer 的指標。 提取程式接著會在每次傳輸數據時重複使用此緩衝區。 當伺服器從用戶端提取數據時,更複雜的用戶端程序可能需要每次配置新的緩衝區。

此範例中的推送程式會使用狀態變數來追蹤下一個位置,其中會將數據儲存在全域數據接收緩衝區中。 它會將數據從管道緩衝區寫入接收緩衝區。 用戶端存根接著會從伺服器接收下一個數據區塊,並將其儲存在管道緩衝區中。 傳送所有數據後,伺服器會傳輸零大小的緩衝區。 這會提示推送程式停止接收數據。

管道

/Oi