TCP セッションの記録に含まれるサンプル コードを示します。
WebTcpipSendBin(hWeb0, "\h0000104F0000005065746572FFFF", 14); // ···O···Peter
ここで、実際に送信され、パラメータ化されるべいビジネス データは、"Peter" = 0x50 65 74 65 72 ですが、ここでは機能しません。"\h0000104F000000" + sName + "\hFFFF" は期待通りの結果にはなりません。問題は、この文字列中の 0 (0x00) バイトによって起こされます。 Silk Performer (C 言語のような) では、0 バイトは文字列の終端として使用されるためです。よって、文字列中の最初の 0 バイトのあとのすべてのバイトがこのような文字列結合の実行中に無視されます。
0 バイトを含む可能性のあるバイナリ データの操作には、関数 SetMem を使用するべきです。以下で詳細を示す関数ライブラリを使用して、上記のリクエストは次の行に分割できます。
ResetRequestData(); AppendRequestData("\h0000104f000000", 7); AppendRequestData(sName); // e.g., "Peter" AppendRequestData("\hFFFF"); SendTcpipRequest(hSend);
関数ライブラリは、インクルード ファイル (*.bdh) を使ってインクルードします。リクエスト データとリクエスト データ長に対して 2 つのグローバル変数を使用します。関数 AppendRequestData は、リクエスト バッファに文字列を追加します (0 バイトを含むことができる)、そして SendTcpipRequest は、開いている TCP 接続を使用してリクエスト データを送信します。
インクルード ファイルの内容は、以下に示すように 3 つの関数で構成されています。
const BUFSIZE := 10000; // maximal size for request data var // global variables for Request data contents and length gsRequestData : string(BUFSIZE); gnRequestLen : number init 0; dclfunc // start a new request string function ResetRequestData begin gnRequestLen := 0; end ResetRequestData; // append data (of length nLen) to the request string // if nLen=0, use strlen(sData) instead function AppendRequestData(sData: string; nLen: number optional): number begin if nLen = 0 then nLen := strlen(sData); end; if nLen + gnRequestLen <= BUFSIZE then // append sData to gsRequestData SetMem(gsRequestData, gnRequestLen + 1, sData, nLen); // the request length has grown by nLen bytes: gnRequestLen := gnRequestLen + nLen; else RepMessage("Request buffer too small!", SEVERITY_ERROR); end; AppendRequestData := gnRequestLen; end AppendRequestData; // Send the request buffer // (TCP-connection identified by hTcp) function SendTcpipRequest (hTcp: number): boolean begin SendTcpipRequest := WebTcpipSendBin(hTcp, gsRequestData, gnRequestLen); end SendTcpipRequest;
レスポンス データに 0 バイトが含まれているとき、文字列を検索することが困難になります。それは、StrSearch および StrSearchDelimited 関数が、対象の文字列を最初の 0 バイトが見つかるまでしか検索を行わないためです。 0 バイトは文字列の終端として解釈されてしまいます。
nPos := BinSearch(sResponseData, nResponseLength, sSearch);
StrSearchDelimited 関数と同等なバイナリ版の関数はありません。.文字列の検索のみを行いたい場合 (0 バイトを含むバイナリ データとは対照的に)、回避策は、レスポンス データからすべての 0 バイトをマッピングによって (たとえば、0xFF バイトに) 最初に削除する関数を導入することです。
このような関数の単純なバージョンを以下に示します。sLeftVal, sRightVal および検索する文字列が文字列である場合にのみ機能します (つまり、0 バイトを含まない)。
function BinSearchDelimited(sSource : string; nSrcLength: number; sLeftVal : string; sRightVal : string) :string(BUFSIZE) var i : number; begin // eliminate zero bytes in the source string for i:=1 to nSrcLength do if ord(sSource[i]) = 0 then sSource[i] := chr(255); end; end; StrSearchDelimited(BinSearchDelimited, BUFSIZE, sSource, sLeftVal, 1, sRightVal, 1, STR_SEARCH_FIRST); end BinSearchDelimited;