2016-02-21 60 views
2

我正在使用delphi(RAD Studio 10)來製作一個小應用程序客戶端和服務器。服務器只發送文字。recv函數不接收所有字節

下一個函數會正確返回發送的字節數。比如我送 '你好'(客戶端):

procedure TTCPConnection.Write(S: String); 
var buff : string; 
begin 
    buff = S+EOL; 
    WriteBuffer(buff, Length(buff)); 
end; 

其中:S = 'hello'EOL = #13#10,所以buff = 'hello'+EOL

procedure TTCPConnection.WriteBuffer(var Buffer; const Len: Cardinal); 
var 
    a : Int16; 
begin 
    a := send(FSocket, Buffer, Len, 0); 
    if (a = SOCKET_ERROR) and FConnected then 
    begin 
    HandleError; 
    Disconnect; 
    end; 
end; 
在前面函數

send(FSocket, Buffer, Len, 0)返回圖7,發送( '你好+ EOL')的字節數。

服務器端:

function TTCPConnection.ReadLn(Delim: String = EOL): String; 
const BUFFER_SIZE = 255; 
var 
    Buff, Buf: string; 
    I, L: Cardinal; 
begin 
    Result := ''; 
    I := 1; 
    L := 1; 
    SetLength(Buff, BUFFER_SIZE); 
    Buf := AnsiString(Buff); 
    while Connected and (L <= Cardinal(Length(Delim))) do 
    begin 
    if recv(FSocket, Buffer, Len, 0) < 1 then exit; 
    Buf := Buff[I]; 
    if Buff[I] = Delim[L] then 
     ... 
    ... 
end; 

(在前面的代碼中,我包括Buf變種僅用於調試目的)。當我調試得到這樣的結果:

Buff = {'h', #0, 'e', #0, 'l', #0, 'l'}(7字節),該行執行recv(FSocket, Buffer, Len, 0)下一次程序什麼也不做,我想這是因爲recv函數無關接收(7個字節發送)。

我需要幫助,使所有字節被正確接收。我不知道他們爲什麼按這個順序(h-#0-e-#0-l-#0-l)。

回答

0

從RAD Studio 2009開始,stringWideChar個字符組成。 CharWideChar的別名,是16位。函數Length()返回字符數,而不是字節。

您可能需要考慮使用TEncoding將字符串轉換爲TBytesarray of byte)以發送,反之亦然。我不知道你的TTCPConnection類,所以它可能是你需要tweek的代碼,但在這裏使用TEncoding.UTF8發送部分:

procedure TTCPConnection.Write(S: String); 
var buff : TBytes; 
begin 
    buff := TEncoding.UTF8.GetBytes(S+EOL); // Convert to bytes using UTF8 encoding 
    WriteBuffer(buff, Length(buff)); 
end; 

這裏是我的接收器代碼在XE5一個testproject我曾經在TTcpServer組件

procedure TForm3.TcpServer1Accept(Sender: TObject; 
    ClientSocket: TCustomIpClient); 
var 
    a: array[0..255] of byte; 
    b: TBytes; 
    i, n: integer; 
    s: string; 
begin 
    n := ClientSocket.ReceiveBuf(a,255,0); 
    SetLength(b, n); 
    for i := Low(b) to High(b) do b[i] := a[i]; // copy from the receive buffer 
    s := TEncoding.UTF8.GetString(b);   // convert UTF8 bytes to string 
    Memo1.Lines.Add(format('%4d %s',[n,s])); 
end; 

最後幾個有用的鏈接的文檔:

TEncoding

UTF-8 Conversion Routines

+0

謝謝。現在recv函數獲得完整的信息。Buff = {'h',#0,'e',#0,'l',#0,'l',#0,'o','$ D',#0, '$ A'}'。現在,我必須建立一個沒有'#0'的新緩衝區?或者我做錯了什麼,這是不是應該顯示? ('Buff = {'h','e','l','l','o','$ D','$ A'}') – Jota69

+0

@Tom您的選擇都不錯。使用UTF16你需要處理排序。如果你想避免使用8位Unicode編碼,UTF8。 –

+0

@ Jota69您需要停止發送文本,並開始考慮將文本編碼爲特定編碼中的二進制文件。 UTF8是最好的選擇。 –

相關問題