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;