Closed k-sareen closed 1 year ago
Pretty much a WIP. Wanted to get your thoughts before I added more support. Note that I've just shoved everything in the Linux x86_64 backend but certain things like InetAddress
should be general across backends.
Here's a sample program to test this:
def main() {
def localhost = Net.LOCALHOST_V4;
def sock = ClientSocket.new(localhost, 5555);
def buffer = Array<byte>.new(512);
System.puts("Hello ");
System.puti(sock.fd);
System.ln();
def ret = sock.connect();
if (ret == -1) {
System.error("Error", "Socket connection failed!");
}
sock.write("Testing\n");
System.puti(sock.read(buffer));
System.ln();
System.puts(buffer);
sock.close();
}
In a separate terminal run ncat -e /bin/cat -k -l 5555 -v
and you should see Testing
print in the terminal running Virgil code.
The current code only implements a client socket -- I'll implement a server socket later.
Couple of things:
InetAddress
is implemented as there is no size for the arrays. Since InetAddress
is a public type, theoretically anyone can create a faulty IP address. Ideally it's a u8[4]
and u8[16]
array for IPv4 and v6 respectively. I have a proposed solution in the comments, but I've just opted for this as it is currently easier to work with.host: string
field for the constructor in SocketBase
instead of the naked InetAddress
. This depends on the API we want to provide to the user.struct
s which aren't stable yet, from my understanding.The x86-linux
backend fails because the lib/util/*.v3
files are added to the -rt.files=
. How am I supposed to add the DataWriter
dependency? I guess once it's in lib/net/x86-64-linux
, it should be fine.
Still not sure how to deal with repeated type definitions for x86_64-linux. Also, apologies, it seems like the x86-linux and x86-64-linux CI configs were swapped. See #118.
I've added the ServerSocket
type now. The server.accept()
function returns another socket for communication. Here's a sample program using this:
def main() {
def any = Net.ANY_V4;
def sock = ServerSocket.new(any, 5555);
def buffer = Array<byte>.new(512);
System.puts("Hello ");
System.puti(sock.fd);
System.ln();
def ret = sock.bind();
if (ret == -1) {
System.error("Error", "Socket connection failed!");
}
sock.listen();
while (true) {
var connection = sock.accept();
if (connection.fd == -1) {
System.error("Error", "Could not accept connections on socket!");
}
System.puts("Connection on fd ");
System.puti(connection.fd);
System.ln();
connection.read(buffer);
System.puts("recv msg: \"");
System.puts(buffer);
System.puts("\"\n");
connection.write("Hello stranger!\n");
connection.close();
}
sock.close();
}
You can use something like ncat 127.0.0.1 5555 -v
or even just the ClientSocket
sample program above (I've edited it to be up-to-date). I have to look into how to support a persistent socket connection so one can send multiple messages in the same session (currently that doesn't work as you will see if you run the above ncat
command and try to send multiple messages).
By the way, is it possible to have private types or classes? I don't want to make the IntPointer
type public, but can't figure out a way to make it private. Also, I personally find not being able to set a def var
field from a subclass a bit non-intuitive. I'm getting around it with a setter-method, but I think it should be allowed generally without a setter-method, no?
Alright -- I've cleaned up a decent amount. I've made it so that you have to manually add the lib/net
library if you want to use it, instead of it being always there. This allows the CI to pass. I think it looks pretty good. I'll add some more comments etc. tomorrow. Let me know if it looks good.
I think after the last two minor changes are addressed, we can land this. Thanks Kunal!
I think after the last two minor changes are addressed, we can land this. Thanks Kunal!
Cool! I've also made the changes regarding the array sizes. I'll push it all in one go.
Cool! I've also made the changes regarding the array sizes. I'll push it all in one go.
I've made the function rangeToInetAddress()
public so that you can easily use it for making your own IP addresses instead of hand-crafting it. As an aside, it'd be good to add tests for it (I've on my own machine tested the generated struct layout and it exactly matches the struct layout from an equivalent C program), but we can figure that out in a future PR.
Merry Christmas! 🎉
This is super cool! I just ran the EchoServer
on one computer and the EchoClient
on another and they were able to talk to each other. Pretty fun. UDP is probably the next thing I'll add.
Thanks Kunal!
This commit adds basic networking support to the x86_64 Linux backend. This commit only implements client sockets.