首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > .NET >

IdTCPClient 发送消息包含中文的变成乱码,麻烦看上小弟我这个代码

2013-01-04 
IdTCPClient 发送消息包含中文的变成乱码,麻烦看下我这个代码unit Unit1interfaceusesWindows, Messages,

IdTCPClient 发送消息包含中文的变成乱码,麻烦看下我这个代码
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, RzPrgres, StdCtrls, IdBaseComponent, IdComponent, IdTCPConnection,
  IdTCPClient, ExtCtrls, XPMan, ComCtrls, Buttons;

type
  TForm1 = class(TForm)
    XPManifest1: TXPManifest;
    tmrCheckServerMsg: TTimer;
    IdTCPClient: TIdTCPClient;
    mmoinfo: TMemo;
    Edtmsg: TEdit;
    btnDisconect: TButton;
    btnConnect: TButton;
    pbProgress1: TRzProgressBar;
    pbProgress: TProgressBar;
    BitBtn1: TBitBtn;
    procedure btnDisconectClick(Sender: TObject);
    procedure EdtmsgKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
    procedure btnConnectClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure IdTCPClientWork(ASender: TObject; AWorkMode: TWorkMode;
      AWorkCount: Int64);
    procedure tmrCheckServerMsgTimer(Sender: TObject);
        private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation
uses TypInfo;
{$R *.dfm}

procedure TForm1.btnConnectClick(Sender: TObject);
var
  Response: string;
  UserName: string;
name:pchar;len:dword;
begin
len:=30;
getmem(name,30);
getcomputername(name,len);
  IdTCPClient.ConnectTimeout := 5000;
  IdTCPClient.Connect;
  username:=name;
  //UserName := Format('U%.5d', [Random(99999)]);
  IdTCPClient.IOHandler.WriteLn(UserName);
  Response := IdTCPClient.IOHandler.ReadLn;
  if SameText(Response, 'LOGINED') then
  begin
    btnDisconect.Enabled := True;
    btnConnect.Enabled := False;
    tmrCheckServerMsg.Enabled := True;
    Caption := 'Client - ' + UserName;
  end
  else raise Exception.CreateFmt('登录失败: "%s"', [Response]);
end;

procedure TForm1.btnDisconectClick(Sender: TObject);
begin
 btnConnect.Enabled:=True;
 btnDisconect.Enabled:=False;
 tmrCheckServerMsg.Enabled:=False;
 Caption:='Client';
 IdTCPClient.Disconnect;
end;

procedure TForm1.EdtmsgKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
 if Key=VK_RETURN then
 begin
  if not IdTCPClient.Connected then Exit;
  if edtMsg.Text<>''then
  begin
   IdTCPClient.IOHandler.WriteLn(edtMsg.Text);


//edtmsg.Text:= EnCodeUTF8(edtMsg.Text);
   mmoInfo.Lines.Add(Format('发送消息:"%s"',[edtMsg.Text]));
   edtMsg.Clear;
  end;
  Key:=0;
 end;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
 try
  if IdTCPClient.Connected then
   btnDisconect.Click;
 except
end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Randomize;
 IdTCPClient.Host:='127.0.0.1';
 IdTCPClient.Port:=7982;
end;

procedure TForm1.FormShow(Sender: TObject);
begin
 form1.btnConnect.Click;
end;

procedure TForm1.IdTCPClientWork(ASender: TObject; AWorkMode: TWorkMode;
  AWorkCount: Int64);
begin
//
pbProgress.Position:=AWorkCount;
 Application.ProcessMessages;
end;

type
  TSizeType = (stB, stK, stM, stG, stT);
function FormatFileSize(Size: Extended; MaxSizeType: TSizeType; var ReturnSizeType: TSizeType;
  const IncludeComma: Boolean = True): string; overload;
const
  FormatStr: array[Boolean] of string = ('0.##', '#,##0.##'); {do not localize}
var
  DivCount: Integer;
begin
  ReturnSizeType := stB;
  DivCount := 0;
  while (Size >= 1024) and (ReturnSizeType <> MaxSizeType) do
  begin
    Size := Size / 1024;
    Inc(DivCount);
    case DivCount of
      1: ReturnSizeType := stK;
      2: ReturnSizeType := stM;
      3: ReturnSizeType := stG;
      4: ReturnSizeType := stT;
    end;
  end;
  Result := FormatFloat(FormatStr[IncludeComma], Size);
end;

function FormatFileSize(Size:Extended;MaxSizeType:TSizeType;
 constIncludeComma:Boolean=True):string;overload;
resourcestring
 RSC_BYTE='字节';
var
 ReturnSt:TSizeType;
begin
 Result:=FormatFileSize(Size,stT,ReturnSt,True)+''+
  Copy(GetEnumName(TypeInfo(TSizeType),Ord(ReturnSt)),3,1);
 if ReturnSt=stB then
 begin
  Delete(Result,Length(Result),1);
  Result:=Result+RSC_BYTE;
 end
 else
  Result:=Result+'B';{donotlocalize}
end;

procedure TForm1.tmrCheckServerMsgTimer(Sender: TObject);
var
 CmdStr:string;
 FSize:Int64;
 FStream:TFileStream;
 SaveFileName:string;
begin
 CmdStr:='';
 if IdTCPClient.Connected then
 begin
  IdTCPClient.IOHandler.CheckForDataOnSource(250);
  if not IdTCPClient.IOHandler.InputBufferIsEmpty then
  begin
   tmrCheckServerMsg.Enabled:=False;
   try
   // CmdStr:=IdTCPClient.IOHandler.ReadLn(enUTF8);
 CmdStr := IdTCPClient.IOHandler.ReadLn;
    CmdStr:=System.UTF8Encode(CmdStr);
    if SameText(Copy(CmdStr,1,4),'FILE')then
    begin
     SaveFileName:=Trim(Copy(CmdStr,5,Length(CmdStr)));
     mmoInfo.Lines.Add('准备接收文件....');
     IdTCPClient.IOHandler.WriteLn('SIZE');
     FSize:=IdTCPClient.IOHandler.ReadInt64(False);
     if FSize>0 then
     begin
      pbProgress.Max:=FSize;
      pbProgress.Position:=0;
            mmoInfo.Lines.Add('文件大小 =' + FormatFileSize(FSize, stK) + '; 正在接收中...');


            IdTCPClient.IOHandler.WriteLn('READY');
      while True do
      begin
       if FileExists(ExtractFilePath(ParamStr(0))+SaveFileName)then
        SaveFileName:='~'+SaveFileName
       else Break;
      end;
      FStream:=TFileStream.Create(ExtractFilePath(ParamStr(0))
       +SaveFileName,
       fmCreate);
      try
       IdTCPClient.IOHandler.LargeStream:=True;
       IdTCPClient.IOHandler.ReadStream(FStream,FSize);
       IdTCPClient.IOHandler.LargeStream:=False;
       IdTCPClient.IOHandler.WriteLn('OK');
       if IdTCPClient.IOHandler.ReadLn='DONE' then
        mmoInfo.Lines.Add('接收成功!')
      finally
       FStream.Free;
      end;
     end
     else begin
      mmoInfo.Lines.Add('接收失败!');
      IdTCPClient.IOHandler.WriteLn('CANCEL');
     end;
    end
    else
     mmoInfo.Lines.Add('接收文本信息:'+CmdStr)
   finally
    tmrCheckServerMsg.Enabled:=True;
   end;
  end;
 end;
end;



end.

收到的消息  中文部分为  '????'     是怎么回事,  麻烦哪位高手指教一下我这个 代码

新手分不多 ,见谅

[解决办法]
编码处理,网络传输二进制流 必须编码 有可能丢失数据

base64编码 后 传输,接收后解码
[解决办法]
服务端与客户端统一编码。
服务端:
cmdstr := AContext.Connection.IOHandler.ReadLn(TEncoding.UTF8);
AContext.Connection.IOHandler.WriteLn('我是中国人', TEncoding.UTF8);

客户端:
IOHandler.WriteLn(cmd, TEncoding.UTF8);
s := IOHandler.ReadLn(TEncoding.UTF8);

热点排行