对不起, 让大家久等了. 现在送上源码主要部分.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ScktComp;
type
TRec = record
Command: Byte;
BufferSize: Integer;
Buffer: PChar;
end;
PRec = ^TRec;
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
ClientSocket1: TClientSocket;
ServerSocket1: TServerSocket;
Memo1: TMemo;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
function Receiver(const APointer: Pointer): LongInt; stdcall;
{ 功能: 接收数据包 }
{ 接收做成这样的函数, 是为并行处理作准备 }
const
MAX_BUF_LEN: Integer = $F000;
var
Buffer: PChar; // 接收缓冲区
ARec: TRec; // 一个纪录
ReceiveLen, BufferSize: Integer; // 接收到的数据长度, 缓冲区大小
AStream: TMemoryStream; // 用来缓冲接收数据
Socket: TCustomWinSocket; // 接收数据的套接字
begin
Socket := TCustomWinSocket(APointer^);
ReceiveLen := Socket.ReceiveLength;
if ReceiveLen > MAX_BUF_LEN then BufferSize := MAX_BUF_LEN
else BufferSize := ReceiveLen;
GetMem(Buffer, BufferSize);
try
AStream := TMemoryStream.Create;
try
{ 分块缓冲接收数据 }
while ReceiveLen > 0 do
begin
BufferSize := Socket.ReceiveBuf(Buffer^, BufferSize); // 接收一块
AStream.Write(Buffer^, BufferSize);
Dec(ReceiveLen, BufferSize);
end;
AStream.Position := 0;
GetMem(Buffer, AStream.Size);
AStream.Read(Buffer^, AStream.Size);
finally
AStream.Free;
end;
ARec := PRec(Buffer)^;
// GetMem(ARec.Buffer, ARec.BufferSize); // 调用 GetMem 重新分配内存则出错!
Form1.Memo1.Lines.Add(ARec.Buffer);
finally
FreeMem(Buffer);
end;
Result := 0;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
ServerSocket1.Port := 1234;
ServerSocket1.Open;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
ClientSocket1.Close;
ClientSocket1.Port := 1234;
ClientSocket1.Host := '127.0.0.1';
ClientSocket1.Open;
end;
procedure TForm1.Button2Click(Sender: TObject);
var
ARec: TRec;
RecSize: Integer;
begin
ARec.BufferSize := 8;
GetMem(ARec.Buffer, ARec.BufferSize);
ARec.Buffer := 'ABCDasda';
RecSize := SizeOf(ARec) + ARec.BufferSize;
ClientSocket1.Socket.SendBuf(ARec, RecSize);
end;
procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
begin
Receiver(Pointer(@Socket));
end;
end.