在用戶端上實作輸出管道
使用輸出管道將資料從伺服器傳輸到用戶端時,您必須在用戶端中實作推送程式。 推送程式會從用戶端存根取得緩衝區的指標和元素計數,如果元素計數大於 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。 當用戶端呼叫遠端程式時,伺服器會開始資料傳輸。 每次資料送達時,用戶端存根都會視需要呼叫用戶端的配置和推送程式。
此範例中的配置程式只會設定變數 globalBuffer 的指標,而不是在每次需要緩衝區時配置記憶體。 提取程式接著會在每次傳輸資料時重複使用這個緩衝區。 每次伺服器從用戶端提取資料時,可能需要配置更複雜的用戶端程式。
此範例中的推送程式會使用狀態變數來追蹤下一個位置,以便將資料儲存在全域資料接收緩衝區中。 它會將資料從管道緩衝區寫入接收緩衝區。 用戶端存根接著會接收來自伺服器的下一個資料區塊,並將其儲存在管道緩衝區中。 傳送所有資料後,伺服器會傳輸零大小的緩衝區。 這會提示推播程式停止接收資料。
相關主題