idTcpServer,多线程下,如何保存客户端的消息记录【CSDN没解决这个问题】(200)

  • 主题发起人 主题发起人 lznet
  • 开始时间 开始时间
L

lznet

Unregistered / Unconfirmed
GUEST, unregistred user!
需求是这样的。Client发送给Server的消息,要保存到一个TXT文本文件中。所以,要考虑到多线程同时操作一个TXT文本的问题。如果服务器保存数据成功,返回给客户端1,如果保存失败,返回给客户端2。兄弟我想到了3个办法。不知道哪个能用。所以,请路过的高手们给一个建议,感谢之至。我考虑的方法1:临界区……Delphi(Pascal) code//全局的
代码:
FLockUI: TCriticalSection;//临界区还有一个TRTLCriticalSection,区别?俺不清楚。反正找个短的来用吧。//改写文本function WriteTxt(Msg: string): Boolean;begin  // .....把接收的数据写入文本的一些程序......  //if 某些条件 then  //  result := true  //else  //  result := false;end;procedure TIndexForm.IdTCPServerExecute(AContext: TIdContext);var IsWrite:Boolean;    ReadString:String;begin  ReadString:=AContext.Connection.IOHandler.ReadLn;  FLockUI.Enter;//考虑容错的话,还可以加入TRY  //这里还可以修改一些控件内容,不如MEMO等;  Memo.Lines.Add(ReadString);  IsWrite := WriteTxt();  if IsWrite then     Client.Context.Connection.IOHandler.WriteLn('1')  else     Client.Context.Connection.IOHandler.WriteLn('0');  FLockUI.Leave;end;
第2中方法:传说中的TIdSync.SynchronizeMethod();对此方法,我了解不深。但某些人说,这不是同步的东西。而且,这东西没有返回值,调用的必须是个过程,没返回值。所以,只能做个全局变量。比如;Delphi(Pascal) code//全局的
代码:
FLockUI: TCriticalSection; //临界区该用还得用。RecStr:String;             //接收到的数据WriteResult:Boolean;       //把接收的数据写入文本的结果procedure WriteText();begin  WriteResult:=false;//让全局的变量为FALSE,默认是写入失败。  // .....把接收的数据写入文本的一些程序......  //if 是否写入成功的条件 then  //  WriteResult := true  //else  //  WriteResult := false;end;procedure TIndexForm.IdTCPServerExecute(AContext: TIdContext);begin  FLockUI.Enter;  //把接收的数据防盗全局变量中  RecStr:=AContext.Connection.IOHandler.ReadLn;  //这里还可以修改一些控件内容,不如MEMO等;  Memo.Lines.Add(ReadString);  //委托到主线程中执行  TIdSync.SynchronizeMethod(WriteText);  if WriteResult then     Client.Context.Connection.IOHandler.WriteLn('1')  else     Client.Context.Connection.IOHandler.WriteLn('0');  FLockUI.Leave;end;
方法三:Windows消息。恐怕很多人都猜出来了。鉴于消息,兄弟我用刚入门,所以,用的不太好。就乱写一下吧。和代码如下:Delphi(Pascal) code
代码:
const  WM_WRITETXT_USERS = WM_USER + 330;//自定义消息类型(这个消息类型范围,从几到几,我还不知道呢)  procedure WMWRITETXTUSERS(var Msg: TMessage); message WM_WRITETXT_USERS;//还得用临界区,因为虽然消息可以跳出线程安全范围,虽然消息可以传递参数,但没有返回值。FLockUI: TCriticalSection; //临界区该用还得用。RecStr:String;             //接收到的数据WriteResult:Boolean;       //把接收的数据写入文本的结果procedure TIndexForm.WMRefreshUsers(var Msg: TMessage);begin  if Msg.Msg = WM_WRITETXT_USERS then     RecStr:=Pchar(Msg.LParam);     WriteText();//在消息里调用写入过程end;procedure WriteText();begin  WriteResult:=false;//让全局的变量为FALSE,默认是写入失败。  // .....把接收的数据写入文本的一些程序......  //if 是否写入成功的条件 then  //  WriteResult := true  //else  //  WriteResult := false;end;procedure TIndexForm.IdTCPServerExecute(AContext: TIdContext);var  RecStr: String;begin  RecStr := AContext.Connection.IOHandler.ReadLn;  FLockUI.Enter;  Memo.Lines.Add(RecStr);  SendMessage(IndexForm.Handle, WM_WRITETXT_USERS, 0, Integer(RecStr));//用消息形式发送出去  //剩下的该怎么弄,就怎么弄……  if WriteResult then     Client.Context.Connection.IOHandler.WriteLn('1')  else     Client.Context.Connection.IOHandler.WriteLn('0');  FLockUI.Leave;end;
以上是我想到的方法,不免有错误的地方。我只想搞明白,如何更安全,如何能完成需求。希望路过的高手不吝赐教……
 
你想多了,文本文件可以同时写的,用共享写模式打开,直接写就行了
 
不需要考虑同步什么的吗?
 
文本文件不用考虑
 
有人说,文本文件共享形式打开,写只能是一个线程,读倒是可以多个线程的。想一起写,不可能的!
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
I
回复
0
查看
566
import
I
I
回复
0
查看
471
import
I
后退
顶部