Indeed I was until Simba spoiled my day.. Sockets in Simba is pure garbage. It sucks in Simba but here goes:
Server:
{$I SRL/SRL.Simba}
type TPacket = record
ID: Integer;
Request: Integer;
Data: String;
end;
Function CreateServerSocket(IP, Port: String): Integer;
begin
Result := CreateSocket;
BindSocket(Result, IP, Port);
ListenSocket(Result);
end;
Procedure TerminateServerSocket(Socket: Integer);
begin
CloseSocket(Socket);
FreeSocket(Socket);
end;
Procedure AcceptServerSocket(Socket: Integer; var Sockets: TIntegerArray);
var
Client, Size: Integer;
begin
try
Client := AcceptSocket(Socket);
if (Client <> 0) then
begin
Size := Length(Sockets);
SetLength(Sockets, Size + 1);
Sockets[Size] := Client;
end;
except
end;
end;
Function ReadPacket(Socket: Integer): TPacket;
begin
Result.ID := StrToIntDef(RecvSocket(Socket), -1);
SendSocket(Socket, ';;;');
Result.Request := StrToIntDef(RecvSocket(Socket), -1);
SendSocket(Socket, ';;;');
Result.Data := RecvSocket(Socket);
SendSocket(Socket, ';;;');
end;
Procedure WritePacket(Socket: Integer; Packet: TPacket);
begin
SendSocket(Socket, ToStr(Packet.ID));
RecvSocket(Socket);
SendSocket(Socket, ToStr(Packet.Request));
RecvSocket(Socket);
SendSocket(Socket, Packet.Data);
RecvSocket(Socket);
end;
Procedure PrintPacket(Packet: TPacket);
begin
writeln('ID: ' + ToStr(Packet.ID));
writeln('Request: ' + ToStr(Packet.Request));
writeln('Data: ' + Packet.Data);
writeln('');
end;
var
Socket, I: Integer;
Packet, Reply: TPacket;
Clients: TIntegerArray;
begin
Socket := CreateServerSocket('127.0.0.1', '27015');
AcceptServerSocket(Socket, Clients);
repeat
For I := 0 To High(Clients) Do
begin
try
if (Clients[I] <> -1) then
begin
writeln('Reading Packet..');
Packet := ReadPacket(Clients[I]);
PrintPacket(Packet);
writeln('Sending Packet..');
Reply.ID := Packet.ID;
Reply.Request := -1;
Reply.Data := 'Sent From Server..';
WritePacket(Clients[I], Reply);
writeln('Packet Sent..');
writeln('');
end;
except
FreeSocket(Clients[I]);
Clients[I] := -1;
TerminateServerSocket(Socket);
TerminateScript;
end;
end;
Sleep(100);
ClearSameIntegers(Clients);
until(False);
TerminateServerSocket(Socket);
end.
Client:
type TPacket = record
ID: Integer;
Request: Integer;
Data: String;
end;
Function ReadPacket(Socket: Integer): TPacket;
begin
Result.ID := StrToIntDef(RecvSocket(Socket), -1);
SendSocket(Socket, ';;;');
Result.Request := StrToIntDef(RecvSocket(Socket), -1);
SendSocket(Socket, ';;;');
Result.Data := RecvSocket(Socket);
SendSocket(Socket, ';;;');
end;
Procedure WritePacket(Socket: Integer; Packet: TPacket);
begin
SendSocket(Socket, ToStr(Packet.ID));
RecvSocket(Socket);
SendSocket(Socket, ToStr(Packet.Request));
RecvSocket(Socket);
SendSocket(Socket, Packet.Data);
RecvSocket(Socket);
end;
Procedure PrintPacket(Packet: TPacket);
begin
writeln('ID: ' + ToStr(Packet.ID));
writeln('Request: ' + ToStr(Packet.Request));
writeln('Data: ' + Packet.Data);
writeln('');
end;
var
Socket: Integer;
Packet: TPacket;
begin
Socket := CreateSocket;
ConnectSocket(Socket, '127.0.0.1', '27015');
Packet.ID := 10;
Packet.Request := 25;
Packet.Data := 'Sent From Client..';
Repeat
try
writeln('Sending Packet..');
WritePacket(Socket, Packet);
writeln('Packet Sent..');
writeln('Reading Packet..');
PrintPacket(ReadPacket(Socket));
writeln('');
except
writeln('Socket Disconnected.');
FreeSocket(Socket);
TerminateScript;
end;
Sleep(100);
Until(False);
CloseSocket(Socket);
FreeSocket(Socket);
end.
Yes it can indeed communicate between Simba's and between Simb and anything else really. You can connect to Smart's socket using Simba and mess shit up lol. You can download pages or files and whatever else. Can communicate to webservers/pages, etc. However, the simba sockets are extremely limited when it comes to server client communicating because the code above is supposed to allow multiple clients to connect to the server. It can't though because Simba isn't multi-threaded and the sockets aren't asynchronous. They are blocking sockets. Every send needs a reply and every reply needs a send to make them non-blocking. Still, that leaves them synchronous and thus one server can only have one client because acceptsocket blocks.
The above works but there's so much more it could do when Simba updates its socket API. For example, reading raw data is a lot harder than in C++. For example, if I wanted to write a structure (aka a Packet Record in pascal) to a socket, I have to stringify the whole thing and read by delimiter. OR write, read, write, read, write, read… and have the server read, write, read, write, read, write. That's the non-blocking pattern.
In C++ and many other languages, you can do: Read(Socket, ByteLength); In Simba it's not byte length. It's string length. And I know strings are made of bytes but Simba's sockets don't read them like that.
For example if I do:
send(sock, data, 4); where data is a byte array containing an integer and 4 is sizeof(int);
I can read 4 bytes and it'll give me a single integer.
Simba simba, you can't do that.. It's:
sendsocket(socket, data, 1); where data is a string holding an integer and 1 is the amount of characters in the string. Thus when reading, you can never tell how much to read. You always have to know that the integer is 1 character in the string. What happens if it is 2-3 characters? Then you need to know this and read 2-3 characters. That's actually stupid because an int is always 4 bytes and you can simply just read 4 bytes and get the whole int.
Meh. I got around that by doing the non-blocking pattern. All that is left is to get Simba asynchronous sockets and some other stuffs and it's good to go. I think Dgby is working on it or whoever it was that told me to hold off/wait. They are busy.