unit Socket_Misk;

interface
Uses Windows,SysUtils, WinSock;
Const
{WM_USER=$0400}
WM_SMTP=$0400+100;

Function InitSocket:Boolean;
Procedure CleanUp;
Function ConnectHost(Port:Integer;Host:String):Boolean;
Function WriteToSocket(Value:String):Boolean;
Function ReadFromSocket:String;
Function SocketResult(Value:String):Integer;
Function InternetDate:string;

Var
MainFormHandle:THandle;
implementation

Var
hSocket:TSocket;
//===================================CleanUp====================================
Procedure CleanUp;
Begin {CleanUp}
If hSocket>0 Then
closesocket(hSocket);
WSACleanup;
End; {CleanUp}
//===================================CleanUp====================================
//******************************************************************************
//==================================InitSocket==================================
Function InitSocket:Boolean;
Var
wVersionRequested:Word;
WSAData:TWSAData;
Begin {InitSocket}
Result:=False;
wVersionRequested:=MakeWord(1,1); //инициализируем сокет Windows
FillChar(WSAData,SizeOf(WSAData),#0);//обнулим все значения WSAData
If Not WSAStartup(wVersionRequested,WSAData)=0 Then //стартуем
Begin {If Not = 0}
//неудача при старте
CleanUp; //уничтожим сокет
Exit;
End; {If Not = 0}
Result:=True;
End; {InitSocket}
//==================================InitSocket==================================
//******************************************************************************
//==================================ConnectHost=================================
Function ConnectHost(Port:Integer;Host:String):Boolean;
Type
TaPInAddr = Array [0..10] Of PInAddr;
PaPInAddr = ^TaPInAddr;
Var
SockAddrIn:TSockAddrIn;
IPAddress:String;
phe: PHostEnt;
pptr: PaPInAddr;
i: Integer;
Begin {ConnectHost}
Result:=False;
//проверка на ХХХ.ХХХ.ХХХ.ХХХ
If inet_addr(PChar(Host))=Socket_ERROR Then
Begin {доменное имя}
//пришло доменное имя, получим из него IP-адрес
phe :=GetHostByName(PChar(Host));
//указанного IP-адреса и не доменного имени не существует
If phe = NIL Then
Begin  {ни то и не другое}
CleanUp;
Exit;
End;   {ни то и не другое}
pptr := PaPInAddr(Phe^.h_addr_list);
i := 0;
While pptr^[i] <> Nil Do
Begin {While}
IPAddress:=StrPas(inet_ntoa(pptr^[i]^));
Inc(i);
End; {While}
End {доменное имя}
Else
IPAddress:=Host;

hSocket:=socket(PF_INET,SOCK_STREAM,0);//создаем сокет
If hSocket=INVALID_SOCKET Then
//неудача при создании сокета
Begin  {INVALID_SOCKET}
CleanUp;
Exit;
End; {INVALID_SOCKET}

SockAddrIn.sin_family:=AF_INET;//укажем тип протокола
SockAddrIn.sin_addr.S_addr:=inet_addr(PChar(IPAddress));//укажем IP-адрес
SockAddrIn.sin_port:=htons(Port); //порт SMTP - 25

If connect(hSocket,SockAddrIn,SizeOf(SockAddrIn))=SOCKET_ERROR Then //соединяемся с сервером
Begin {SOCKET_ERROR}
//неудача при соедении с сервером
CleanUp;
Exit;
End; {SOCKET_ERROR}
Result:=True;
End;  {ConnectHost}
//==================================ConnectHost=================================
//******************************************************************************
//=================================WriteToSocket================================
Function WriteToSocket(Value:String):Boolean;
Var
Buffer:Array[0..1024] Of Char;
Begin {WriteToSocket}
Result:=False;
FillChar(Buffer,SizeOf(Buffer),#0);
Value:=Value+#13#10;
StrPCopy(Buffer,Value);
SendMessage(MainFormHandle,WM_SMTP,0,lParam(@Value[1]));
//отправим данные в сокет
If send(hSocket,Buffer,Length(Value),0)=SOCKET_ERROR Then
Begin {неудача, выходим}
CleanUp;
Exit;
End; {неудача, выходим}
Result:=True;
End;  {WriteToSocket}
//=================================WriteToSocket================================
//******************************************************************************
//=================================ReadFromSocket===============================
Function ReadFromSocket:String;
Var
Buffer:Array[0..1024] Of Char;
Begin {ReadFromSocket}
Result:='';
FillChar(Buffer,SizeOf(Buffer),#0);
If recv(hSocket,Buffer,SizeOf(Buffer),0)<1 Then
Begin
CleanUp;
Result:='Error socket read!';
End
Else
Result:=String(Buffer);

SendMessage(MainFormHandle,WM_SMTP,1,lParam(@Result[1]));
End;  {ReadFromSocket}
//=================================ReadFromSocket===============================
//******************************************************************************
//===================================SocketResult===============================
Function SocketResult(Value:String):Integer;
Begin {SocketResult}
Result:=0;
If Length(Value)>3 Then
Result:=StrToInt(Copy(Value,1,3))
Else
CleanUp;
End;  {SocketResult}
//===================================SocketResult===============================


Function InternetDate:string;
const
  weekdays:array[1..7] of string[3]=('Sun','Mon','Tue','Wed','Thu','Fri','Sat');
  months:array[1..12] of string[3]=('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec');
var
bias: longint;
TZI:TTimeZoneInformation;
timezone:String;
d,m,y,w,h,mm,s,ms: word;
begin
FillChar(TZI,SizeOf(TZI),#0);
GetTimeZoneInformation(TZI);
bias:=TZI.Bias;
timezone:=FormatFloat('00',abs(bias) div 60)+ FormatFloat('00',abs(bias) mod 60);
if bias=0 then timezone:='GMT';
if bias<0 then timezone:='+' + timezone;
if bias>0 then timezone:='-' + timezone;
Result:=timezone;
DecodeDate(Now,y,m,d);
DecodeTime(Now,h,mm,s,ms);
w:=DayOfWeek(Now);
Result:=weekdays[w]+', '+IntToStr(d)+' '+months[m]+' '+inttostr(y)+' '+
FormatFloat('00',h)+':'+FormatFloat('00',mm)+':'+FormatFloat('00',s)+' '+timezone;
end;


end.

