program socket_server;
{$mode objfpc}{$H+}
{
Program to test sockets and get working example of Sockets unit.
This is the single thread server part.
Use the client part to send data to that server.
Inspired from fpConnect / fpAccept examples
}
uses
{$IFDEF UNIX}
cthreads,
{$ENDIF}
Classes,
Sockets,
SysUtils
{ you can add units after this };
var
// Sockets descriptors
SockDesc: longint;
clientId: longint;
// Sockets addresses
SockAddr: TInetSockAddr;
ClientAddr: TInetSockAddr;
// Message
Buffer: array [1..30] of char;
Mensaje: string;
AddrSize: longint;
RecvSize: longint;
StartTimer: longint;
procedure perror(const S: string);
var
ErrorMsg: string;
begin
case socketerror of
EsockADDRINUSE: ErrorMsg := 'Error number when socket address is already in use';
EsockEACCESS: ErrorMsg := 'Access forbidden error';
EsockEBADF: ErrorMsg := 'Alias: bad file descriptor';
EsockEFAULT: ErrorMsg := 'Alias: an error occurred';
EsockEINTR: ErrorMsg := 'Alias : operation interrupted';
EsockEINVAL: ErrorMsg := 'Alias: Invalid value specified';
EsockEMFILE: ErrorMsg := 'Error code ?';
EsockEMSGSIZE: ErrorMsg := 'Wrong message size error';
EsockENOBUFS: ErrorMsg := 'No buffer space available error';
EsockENOTCONN: ErrorMsg := 'Not connected error';
EsockENOTSOCK: ErrorMsg := 'File descriptor is not a socket error';
EsockEPROTONOSUPPORT: ErrorMsg := 'Protocol not supported error';
EsockEWOULDBLOCK: ErrorMsg := 'Operation would block error';
else
ErrorMsg := 'Undescribed error : ' + IntToStr(socketerror);
end;
writeln(S, ErrorMsg);
halt(100);
end;
begin
SockDesc := fpSocket(AF_INET, SOCK_STREAM, 0);
if SockDesc = -1 then
Perror('[Server] Socket : ');
SockAddr.sin_family := AF_INET;
// Port 8008
SockAddr.sin_port := htons(8008);
// Look on all interfaces so address 0.0.0.0
SockAddr.sin_addr := StrToNetAddr('0.0.0.0');
// Bind socket
if fpBind(SockDesc, @SockAddr, sizeof(SockAddr)) = -1 then
PError('[Server] Bind : ');
// Turn socket into listening state
if fpListen(SockDesc, 1) = -1 then
PError('[Server] Listen : ');
// Waiting client connection
Writeln('Waiting for client connection, run now client in an other tty');
// Accept client connection
AddrSize := sizeof(ClientAddr);
while True do
begin
clientId := fpAccept(SockDesc, @ClientAddr, @AddrSize);
if clientId = -1 then
PError('[Server] Accept : ' + NetAddrToStr(ClientAddr.sin_addr))
else
writeln('[Server] New client connected from: ' + NetAddrToStr(ClientAddr.sin_addr));
// Read data
RecvSize := fprecv(clientId, @Buffer, SizeOf(Buffer), 0);
Mensaje := Buffer;
while RecvSize > 0 do
begin
if RecvSize > 0 then
writeln('[Server] Receive : ' + Mensaje + ' [' + IntToStr(RecvSize) + ']');
RecvSize := fprecv(clientId, @Buffer, SizeOf(Buffer), 0);
Mensaje := Buffer;
end;
if (RecvSize = 0) and (SocketError = 0) then
begin
writeln('[Server] Client disconnect.');
writeln('');
end;
if RecvSize = -1 then
PError('[Server] Read failed : ');
end;
end.