delphi中使用SocketStream读写数据的技巧

procedure TServerThread.ClientExecute;
var
    pStream:TWinSocketStream;
    buffer:Pointer;
    readText,SendText:string;
    i:integer;
Const
{读客户端令牌时使用的缓冲区大小,因为它们都是一些字符串,所以定义为1024byte足够了}
    ReadLen=1024;
begin

{创建连接流对象,以便和客户端交流}
      pStream:=TWinSocketStream.Create(ClientSocket,60000);
      try
      {ClientSocket是TServerClientThread 类内置的一个对象,它是和客户端连接的套接字}
      while (not Terminated) and ClientSocket.Connected do
      begin
        try
        {分配读数据缓冲区}
        Buffer:=AllocMem(readLen);
        if PStream.WaitForData(6000) then
        begin
          pStream.Read(Buffer^,ReadLen);    ///读取客户端发送data,数据是从缓存区中读取。 readText:=Pchar(Buffer);
          FreeMem(buffer);
          //客户端请求验证是否有可以更新的文件
          if ReadText = Key_Clt[1] then
          begin
            Synchronize(listItemAdd);//多线程中同步信息需要调用的方法。
            SendText:=Key_Srv[1]+stringstostring(FilesNameSepstr,filesName,true);
            {特别注意SendText后应该加上索引1,指定write方法从SendText第一个字符
            开始读,否则默认从0开始}
            pStream.Write(SendText[1],length(sendtext)+1);//向客户端写数据
          end

except

errorRaise:=true;
    Terminate;

end;

end;
        finally
          pstream.Free;
          ClientSocket.Close;
      end;
end;

由于Socket选择 使用ctBlock的方式,所以在接收、发送数据时,就不能依靠在OnRead,OnWrite中读取和写入数据了,因为该事件在ctBlock下根本就不能被触发。
   解决的方法就是不间断的监听线程

while (not Terminated) and ClientSocket.Connected do
begin

end;

读取数据的时机:if PStream.WaitForData(6000) then
        begin
        end;

转自:http://gykthh.blog.163.com/blog/static/6453464200852710710790/

-----------------------------------------------------------------------------------------------------------------------------

{ TFileServerThread }

TFileServerThread = class(TServerClientThread)
  public
    procedure ClientExecute; override;
  end;

{ TFileServerThread }

procedure TFileServerThread.ClientExecute;
var
  Data : array[0..1023] of char;
  RecText : string;
  SocketStream : TWinSocketStream;
begin

While Not Terminated And ClientSocket.Connected Do
  Try
    SocketStream := TWinSocketStream.Create(ClientSocket, 30000);
    Try
      FillChar(Data, SizeOf(Data), 0);
      If SocketStream.Read(Data, SizeOf(Data)) = 0 Then
      Begin
        // If we didn‘t get any data after xx seconds then close the connection
        ClientSocket.SendText(‘Timeout on Server‘+#13#10);
        //Wait a little time to allow sending of text before disconnect
        sleep(1);
        ClientSocket.Close;
        Terminate;
      End;
      RecText := Data;
      If Length(RecText) > 2 Then
        Delete(RecText, Pos(#13#10, RecText), 2); // Delete #13#10
      If ClientSocket.Connected Then
      Begin
        ClientSocket.SendText(RecText);
        SendMessage(Form1.Listbox1.Handle, LB_ADDSTRING, 0, Integer(PChar(RecText)));
        PostMessage(Form1.Handle, CM_INCCOUNT, 0, 0);
      End;
    Finally
      SocketStream.Free;
    End;
  Except
    HandleException;
  End; 
end;

procedure TForm1.ServerSocketGetThread(Sender: TObject;
  ClientSocket: TServerClientWinSocket;
  var SocketThread: TServerClientThread);
begin
  SocketThread := TFileServerThread.Create(False, ClientSocket);
end;

-----------------------------------------------------------------------------------------------------------------------------

delphi的帮助中有Writing client threads 和 Writing server threads代码示例。
procedure
TMyClientThread.Execute;
var
TheStream: TWinSocketStream;
buffer:
string;
begin
{ create a TWinSocketStream for reading and writing }

TheStream := TWinSocketStream.Create(ClientSocket1.Socket, 60000);
try

{ fetch and process commands until the connection or thread is terminated
}
while (not Terminated) and (ClientSocket1.Active) do
begin

try
GetNextRequest(buffer); { GetNextRequest must be a thread-safe
method }

{ write the request to the server }

TheStream.Write(buffer, Length(buffer) + 1);
{ continue the
communication (e.g. read a response from the server) }
...

except
if not(ExceptObject is EAbort) then

Synchronize(HandleThreadException); { you must write HandleThreadException }

end;
end;
finally
TheStream.free;
end;
end;

procedure TMyServerThread.ClientExecute;
var
Stream :
TWinSocketStream;
Buffer : array[0 .. 9] of Char;
begin
{ make
sure connection is active }
while (not Terminated) and
ClientSocket.Connected do
begin
try
Stream :=
TWinSocketStream.Create(ClientSocket, 60000);
try

FillChar(Buffer, 10, 0); { initialize the buffer }
{ give the client
60 seconds to start writing }
if Stream.WaitForData(60000) then

begin
if Stream.Read(Buffer, 10) = 0 then { if can‘t
read in 60 seconds }
ClientSocket.Close; { close
the connection }
{ now process the request }
...

end
else
ClientSocket.Close; { if client doesn‘t
start, close }
finally
Stream.Free;
end;

except
HandleException;
end;
end;
end;

时间: 2024-10-27 18:31:37

delphi中使用SocketStream读写数据的技巧的相关文章

Delphi中Json格式读写

Json是一种轻量级数据传输格式,广泛应用互联网和各应用中,json主要采用键值对来表示数据项,多个数据项之间用逗号分隔,也可以用于数组.下面注重介绍一下在delphi中使用json,在delphi中使用json常用superobject单元文件,该文件可以在网上下载,最初接触json是在2011年,好久没用这不刚好有项目要用到又折腾了好久,下面做了一个简单的Demo,方便以后忘了能随时查看,具体的json使用可以参看万一老师的博客,记录的很详细,下面的demo主要是将数据库记录转换为json格

Delphi中清除窗体编号数据

procedure TForm1.Button1Click(Sender: TObject); var i:integer; begin for i:=0 to self.ComponentCount-1 do begin if (self.Components[i] is Tedit) then begin Tedit(Components[i]).Clear;; end; end; end;

ActiveX数据对象之事务控制在VB和DELPHI中的应用

本文发表在中国人民解放军"信息工程大学"学报 2001年第3期. ActiveX数据对象之事务控制在VB和DELPHI中的应用                     马根峰1   ,  孙艳2  , 宋伟1                       ( 1.重庆邮电学院 ,重庆,400065 :2. 铁道部第十九工程局四处,通辽,028000  ) 摘要      事务控制是数据库应用系统中的关键技术之一,本文一开始先对事务控制的概念以及微软的 ActiveX数据对象(ADO)的事

Delphi中根据分类数据生成树形结构的最优方法

一. 引言:    TreeView控件适合于表示具有多层次关系的数据.它以简洁的界面,表现形式清晰.形象,操作简单而深受用户喜爱.而且用它可以实现ListView.ListBox所无法实现的很多功能,因而受到广大程序员的青睐.    树形结构在Windows环境中被普遍应用,但在数据库开发中面对层次多.结构复杂的数据,如何快速构造树形目录并实现导航呢?    二. 实现关键技术:    在Delphi提供的控件中包含了TreeView控件,但树的具体形成还需要用户编写代码.即它的列表项要在程序

Delphi中多线程用消息实现VCL数据同步显示

Delphi中多线程用消息实现VCL数据同步显示 Lanno Ckeeke 2006-5-12 概述: delphi中严格区分主线程和子主线程,主线程负责GUI的更新,子线程负责数据运算,当数据运行完毕后,子线程可以向主线程式发送消息,以便通知其将VCL中的数据更新. 实现: 关键在于消息的发送及接收.在消息结构Tmessage中wParam和lParam类型为Longint,而指针类型也定义为Longint,可以通过此指针来传递自己所感兴趣的数据.如传递字符数组: 数组定义: const MA

Hadoop 中利用 mapreduce 读写 mysql 数据

Hadoop 中利用 mapreduce 读写 mysql 数据 有时候我们在项目中会遇到输入结果集很大,但是输出结果很小,比如一些 pv.uv 数据,然后为了实时查询的需求,或者一些 OLAP 的需求,我们需要 mapreduce 与 mysql 进行数据的交互,而这些特性正是 hbase 或者 hive 目前亟待改进的地方. 好了言归正传,简单的说说背景.原理以及需要注意的地方: 1.为了方便 MapReduce 直接访问关系型数据库(Mysql,Oracle),Hadoop提供了DBInp

Delphi中WebBrowser的使用技巧汇总

1>调用网页中已知对象 src := WebBrowser1.OleObject.document.getElementByIdx(’id1′).src 其实就是javascript中的 getElementByID 的函数 2>获得网页中的某个变量值 Html中的代码 : <script> var userID=123</script> 在delphi程序中这么调用 id := Form1.WebBrowser1.OleObject.Document.script.u

MATLAB中文件的读写和数据的导入导出

http://blog.163.com/tawney_daylily/blog/static/13614643620111117853933/ 在编写一个程序时,经常需要从外部读入数据,或者将程序运行的结果保存为文件.MATLAB使用多种格式打开和保存数据.本章将要介绍 MATLAB中文件的读写和数据的导入导出. 13.1 数据基本操作 本节介绍基本的数据操作,包括工作区的保存.导入和文件打开.13.1.1 文件的存储 MATLAB支持工作区的保存.用户可以将工作区或工作区中的变量以文件的形式保

Delphi中使用python脚本读取Excel数据

Delphi中使用python脚本读取Excel数据2007-10-18 17:28:22标签:Delphi Excel python原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://seewind.blog.51cto.com/249547/46669前段时间,在正式项目中使用Python来读取Excel表格的数据.具体需求是,项目数据库中有些数据需要根据Excel表格里面的数据进行一些调整,功能应该比较简单.为了学习Pyth