program clumsyexample;
{$mode objfpc}{$h+}
uses
sockets, sysutils;
procedure Inform(condition: boolean; trues, falses: string);
var
errcode: integer;
errstr : string;
begin
if condition then writeln(trues) else
begin
errcode := GetLastOSError;
errstr := SysErrorMessage(errcode);
writeln('ERROR: ', falses, ' (error code ', errcode, ' = ', errstr,')');
end;
end;
procedure client;
var
sock : TSocket;
optval : int32 = 1;
remotipstr : string = '127.0.0.1';
remotport : integer = 8888;
remotaddr : TSockAddr;
msg : pchar = 'hello world';
retval : integer;
begin
remotaddr.sin_family := AF_INET;
remotaddr.sin_port := htons(remotport);
remotaddr.sin_addr := StrToNetAddr(remotipstr);
sock := fpsocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
inform(sock <> -1, 'new socket created', 'unable to create new socket');
retval := fpsetsockopt(sock, SOL_SOCKET, SO_BROADCAST, @optval, sizeof(optval));
inform(retval <> -1, 'socket option set', 'unable to set socket option');
retval := fpsendto(sock, msg, length(msg), 0, @remotaddr, sizeof(remotaddr));
inform(retval <> -1, 'message broadcasted', 'unable to broadcast message');
retval := closesocket(sock);
inform(retval <> -1, 'socket closed', 'unable to close socket');
end;
procedure server;
var
sock : TSocket;
localaddr : TSockAddr;
localport : integer = 8888;
remotaddr : TSockAddr;
len : integer;
retval : integer;
slen : TSockLen;
buf : array[0..200] of char;
begin
localaddr.sin_family := AF_INET;
localaddr.sin_port := htons(localport);
localaddr.sin_addr.s_addr := htonl(INADDR_ANY);
sock := fpsocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
inform(sock <> -1, 'new socket created', 'unable to create new socket');
retval := fpbind(sock, @localaddr, sizeof(localaddr));
inform(retval <> -1, 'bind succeeded', 'unable to bind socket');
slen := SizeOf(remotaddr);
while true do
begin
writeln('waiting for data...');
len := fprecvfrom(sock, @buf[0], sizeof(buf), 0, @remotaddr, @slen);
inform(len <> -1, 'message received', 'unable to receive message');
if len <> -1 then
begin
writeln
(
format('received message "%s" from %s:%d',
[copy(buf, 0, len), NetAddrToStr(remotaddr.sin_addr), ntohs(remotaddr.sin_port)])
);
end;
end;
retval := closesocket(sock);
inform(retval <> -1, 'socket closed', 'unable to close socket');
end;
begin
if (paramcount = 1) and (paramstr(1) = 'client') then
begin
writeln('start client');
client;
end
else
begin
writeln('start server');
server;
end;
end.