Receiving and responding HTTP messages using TCP sockets
Posted: (EET/GMT+2)
The HTTP protocol operates over TCP, and from a programming perspective, you can use network sockets for implementing the communications. I'm showing below how you can use Delphi to work with the HTTP protocol.
First, you need to open a socket in listening mode. The default HTTP port number is 80, but you can use any port you like. Since sockets can communicate in both directions, it is best to use the Delphi TThread class. Here is an example of opening a socket:
uses
Classes, WinSock;
Const
HTTPListenPort = 80;
...
Procedure TAcceptor.CreateListenSocket;
Var
Name : TSockAddr;
I : Integer;
Begin
Socket := WinSock.Socket(af_Inet,sock_Stream,IPProto_TCP);
If (Socket = Invalid_Socket) Then Begin
Msg := 'Acceptor: Can''t create socket: '+IntToStr(WSAGetLastError);
Synchronize(DisplayMessage);
Exit;
End;
With Name do Begin
sin_Family := pf_Inet;
sin_Port := htons(HTTPListenPort);
I := htonl(InAddr_Any);
sin_Addr := TInAddr(I);
End;
I := Bind(Socket,Name,SizeOf(Name));
If (I = SOCKET_ERROR) Then Begin
Msg := 'Acceptor: Can''t bind: '+IntToStr(WSAGetLastError);
Synchronize(DisplayMessage);
Exit;
End;
I := Listen(Socket,3);
If (I = SOCKET_ERROR) Then Begin
Msg := 'Acceptor: Can''t listen: '+IntToStr(WSAGetLastError);
Synchronize(DisplayMessage);
Exit;
End;
Msg := 'Acceptor: Waiting for connections...';
Synchronize(DisplayMessage);
End;
The next step is to create a HTTP request processor. Again, this should be a custom descendant class of TThread. Here is a simple example:
procedure THTTPRequest.Execute;
Var
Buf : Array[0..512000] of Char; { HTTP data must be less than 500k }
I : Integer;
Name : TSockAddr;
S : String;
begin
Try
I := Recv(Socket,Buf,SizeOf(Buf),0);
If (I = SOCKET_ERROR) Then Begin
Msg := 'Request: Can''t receive header: '+IntToStr(Socket)+' '+IntToStr(WSAGetLastError);
Synchronize(DisplayMessage);
Exit;
End;
S := 'Hello HTTP from Delphi!';
I := Send(Socket,S[1],Length(S),0);
If (I = SOCKET_ERROR) Then Begin
Msg := 'Request: Can''t send: '+IntToStr(WSAGetLastError);
Synchronize(DisplayMessage);
Exit;
End;
Finally
CloseSocket(Socket);
End;
end;
If you put these two pieces of code together, you can respond to HTTP requests without any web server.
Remember that you need to initialize and shut Winsock down with WSAStartup and WSACleanup. Otherwise, you cannot create socket connections.