Проект в первоначальном виде опубликовал в Инете Н.Карих. Здесь этот проект приспособлен для работы с POP3-сервером.
При отлаживании проекта весьма полезным оказалась программа SocketSpy, разработанная Franois PIETTE (francois.piette@rtfm.be http://www.overbyte.be wilfried@mestdagh.biz ). Эта программа показывает содержимое сообщений, передаваемых от клиента - серверу и обратно.
Скачать SocketSpy.rar (180Kb) можно здесь SocketSpy.rar.
{ Учебный проект.}
unit Unit4;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ScktComp, ComCtrls;
type
TForm1 = class(TForm)
Label1: TLabel;
Edit1: TEdit;
Label2: TLabel;
Edit2: TEdit;
Button1: TButton;
Label3: TLabel;
Edit3: TEdit;
Label4: TLabel;
Edit4: TEdit;
SB1: TStatusBar;
Memo1: TMemo;
Label5: TLabel;
edCmd: TEdit;
Label6: TLabel;
btnCmd: TButton;
procedure Button1Click(Sender: TObject);
procedure ClientSocket1Connect(Sender: TObject; Socket: TCustomWinSocket);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure btnCmdClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
ClientSocket1: TClientSocket;
implementation
{$R *.DFM}
var MySocket: TWinSocketStream; lada: Integer;
procedure TForm1.Button1Click(Sender: TObject);
begin
{Присваиваем свойствам Host и Port нужные значения}
ClientSocket1.Host := Edit1.Text;
ClientSocket1.Port := StrToInt(Edit2.Text);
{Пытаемся открыть сокет и установить соединение}
ClientSocket1.Open;
end;
function ReadLine(): string;
var bufbuf: array [0..1023] of char;
Count,ii: Integer; FromServ:string;
begin
if MySocket.WaitForData(60000) then
begin
FillChar(Bufbuf,1024,0);
Count:= MySocket.Read(Bufbuf,1024);
if Count = 0 then
begin
// ClientSocket1.Close;
result:= '';
exit;
end;
FromServ:='';
for ii:=0 to Count-1 do
FromServ:= FromServ + BufBuf[ii];
end else
ClientSocket1.Close;
Result:= FromServ;
lada:= 4;
end;
procedure TForm1.ClientSocket1Connect(Sender: TObject;
Socket: TCustomWinSocket);
var login,password,ll,pp,rl: string; Count1: Integer;
begin
SB1.SimpleText:= 'Подключился';
MySocket := TWinSocketStream.Create(Socket,60000);
{Добавляем к логину и паролю символ перевода строки,
чтобы сервер смог отделить логин и пароль.}
Memo1.Clear;
Repeat
rl:= rl + ReadLine();
until pos(#13#10,rl) > 0 ;
Memo1.Lines.Append('Serv: '+copy(rl,1,length(rl)-2));
login := 'user ' + Edit3.Text;
password := 'pass ' + Edit4.Text;
ll:= login + #13#10;
pp:= password + #13#10;
try
Count1:= MySocket.Write(ll[1],Length(ll));
Memo1.Lines.Append('Cli :' + login);
// rl:= ReadLine();
rl:= '';
Repeat
rl:= rl + ReadLine();
until pos(#13#10,rl) > 0 ;
Memo1.Lines.Append('Serv: ' + copy(rl,1,length(rl)-2));
MySocket.Write(pp[1], Length(pp) );
Memo1.Lines.Append('Cli :' + password);
// rl:= ReadLine();
rl:= '';
Repeat
rl:= rl + ReadLine();
until pos(#13#10,rl) > 0 ;
Memo1.Lines.Append('Serv: '+copy(rl,1,length(rl)-2));
Memo1.Lines.Append('Вводите любые команды POP3');
Memo1.Lines.Append('Например: LIST, RETR 1, TOP 2 5,');
Memo1.Lines.Append('DELE 2, STAT');
Memo1.Lines.Append('--- QUIT - выход ------');
Memo1.Lines.Append(' ');
except
SB1.SimpleText:= 'Не подключился';
end;
end;
procedure TForm1.btnCmdClick(Sender: TObject);
var rl,rl2,cmd,cmd2: string; poza: Integer;
begin
cmd:= edCmd.Text;
cmd2:= cmd + #13#10;
MySocket.Write(cmd2[1], Length(cmd2));
Memo1.Lines.Append('Cli: ' + cmd);
rl:= '';
Repeat
rl:= rl + ReadLine();
until pos(#13#10+'.'+#13#10,rl) > 0 ;
Memo1.Lines.Append('Serv: '+ rl);
{ Repeat
showmessage(rl+' '+ IntToStr(length(rl)));
poza := pos(#13#10,rl);
if poza < 1 then break;
rl2:= copy(rl,1,poza-1);
if rl2 <> '' then
Memo1.Lines.Append('Serv: '+ rl2) else
Memo1.Lines.Append('----------');
delete(rl,1,poza+1);
until false; }
// until rl='.';
// except
// showmessage('Ошибка чтения');
// end;
Memo1.Lines.Append('<<<<<< Команда исполнена >>>>>>');
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
ClientSocket1:= TClientSocket.Create(Self);
with ClientSocket1 do
begin
OnConnect:= ClientSocket1Connect;
Active:= False;
ClientType:= ctBlocking;
Port:= 0;
end;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
MySocket.Free;
ClientSocket1.Close;
ClientSocket1.Free;
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;
*)
end.
Скачать RAR-архив исходников + .exe(380 Кб)