From 0a51c54040064bbff559465b97ab0baa86ecf9cb Mon Sep 17 00:00:00 2001 From: SpookyDervish Date: Fri, 10 Jul 2026 08:55:06 +1000 Subject: [PATCH] core client and server methods implemented --- client.comet | 17 +++++++ test.comet => server.comet | 13 +++--- src/address.c | 25 +++++++++++ src/address.h | 8 ++++ src/main.c | 2 + src/socket.c | 92 +++++++++++++++++++++++++++++++++++--- 6 files changed, 145 insertions(+), 12 deletions(-) create mode 100644 client.comet rename test.comet => server.comet (54%) create mode 100644 src/address.c create mode 100644 src/address.h diff --git a/client.comet b/client.comet new file mode 100644 index 0000000..9ddf841 --- /dev/null +++ b/client.comet @@ -0,0 +1,17 @@ +import socket +import io + +func main() -> int { + socket.Socket s = new socket.Socket(socket.Family.INET, socket.Type.STREAM, 0) + + io.println("Connecting...") + s.connect("127.0.0.1", 2000) + + io.println("Sending data...") + s.send("hi!") + + io.println("Closing socket...") + s.close() + + return 0 +} \ No newline at end of file diff --git a/test.comet b/server.comet similarity index 54% rename from test.comet rename to server.comet index 440569c..c2aa463 100644 --- a/test.comet +++ b/server.comet @@ -3,11 +3,14 @@ import io func main() -> int { socket.Socket s = new socket.Socket(socket.Family.INET, socket.Type.STREAM, 0) - - s.connect("142.250.188.46", 80) - s.send("GET / HTTP/1.1\r\nHost: google.com\r\n\r\n") - - string response = s.recv(1024) + + s.bind("127.0.0.1", 2000) + + s.listen(10) + socket.Socket client = s.accept() + io.println("Connection received!") + + string response = client.recv(256) io.println("Response: %s", response) s.close() diff --git a/src/address.c b/src/address.c new file mode 100644 index 0000000..63d3e5b --- /dev/null +++ b/src/address.c @@ -0,0 +1,25 @@ +#include "address.h" + +ResultType(int64_t, objectPtr) impl_Address_INIT(int64_t* args, CometVM* vm) { + CometObject* self = (CometObject*)args[0]; + + self->fields[0] = args[1]; + self->fields[1] = args[2]; + + return Success(int64_t, objectPtr, (int64_t)self); +} + +CometStruct* defineAddressStruct(CometEnvironment* env) { + CometStruct* addressStruct = cometDefineStruct(env, "Address", NULL); + + List(StructField) fields = newList(StructField); + append(fields, cometCreateField("ip", cometTypeString, FIELD_PUBLIC)); + append(fields, cometCreateField("port", cometTypeInt, FIELD_PUBLIC)); + + List(externalMethodPtr) methods = newList(externalMethodPtr); + + cometSetStructFieldsAndMethods(addressStruct, fields, methods); + cometDefineConstructor(env, addressStruct, 2, false, cometTypeString, cometTypeInt); + + return addressStruct; +} \ No newline at end of file diff --git a/src/address.h b/src/address.h new file mode 100644 index 0000000..874d633 --- /dev/null +++ b/src/address.h @@ -0,0 +1,8 @@ +#ifndef ADDRESS_H +#define ADDRESS_H + +#include + +CometStruct* defineAddressStruct(CometEnvironment* env); + +#endif \ No newline at end of file diff --git a/src/main.c b/src/main.c index e12a8ee..bccb2e6 100644 --- a/src/main.c +++ b/src/main.c @@ -1,6 +1,8 @@ #include #include "socket.h" +#include "address.h" on_import { defineSocketStruct(env, typeMap); + defineAddressStruct(env); } \ No newline at end of file diff --git a/src/socket.c b/src/socket.c index 6df66e9..b49f5f9 100644 --- a/src/socket.c +++ b/src/socket.c @@ -23,6 +23,16 @@ ResultType(int64_t, objectPtr) impl_Socket_INIT(int64_t* args, CometVM* vm) { return Success(int64_t, objectPtr, (int64_t)self); } +struct sockaddr_in createIPV4Address(int family, char* ip, int port) { + struct sockaddr_in address; + + inet_pton(family, ip, &address.sin_addr.s_addr); + address.sin_family = family; + address.sin_port = htons(port); + + return address; +} + ResultType(int64_t, objectPtr) impl_connect(int64_t* args, CometVM* vm) { char* ip = cometArgString(args[0]); int port = cometArgInt(args[1]); @@ -31,12 +41,7 @@ ResultType(int64_t, objectPtr) impl_connect(int64_t* args, CometVM* vm) { int fd = self->fields[0]; int family = self->fields[1]; - // create the address struct - struct sockaddr_in address; - - inet_pton(family, ip, &address.sin_addr.s_addr); - address.sin_family = family; - address.sin_port = htons(port); + struct sockaddr_in address = createIPV4Address(family, ip, port); // then connect int result = connect(fd, (struct sockaddr*)&address, sizeof(address)); @@ -49,6 +54,64 @@ ResultType(int64_t, objectPtr) impl_connect(int64_t* args, CometVM* vm) { return Success(int64_t, objectPtr, 0); } +ResultType(int64_t, objectPtr) impl_bind(int64_t* args, CometVM* vm) { + char* ip = cometArgString(args[0]); + int port = cometArgInt(args[1]); + CometObject* self = (CometObject*)args[2]; + + int fd = self->fields[0]; + int family = self->fields[1]; + + struct sockaddr_in address = createIPV4Address(family, ip, port); + + + int result = bind(fd, (struct sockaddr*)&address, sizeof(address)); + if (result != 0) { + char* errMsg = strerror(errno); + return cometError(vm, "SocketError", errMsg); + } + + return Success(int64_t, objectPtr, 0); +} + +ResultType(int64_t, objectPtr) impl_listen(int64_t* args, CometVM* vm) { + int backlog = cometArgInt(args[0]); + CometObject* self = (CometObject*)args[1]; + + int fd = self->fields[0]; + + int result = listen(fd, backlog); + if (result != 0) { + char* errMsg = strerror(errno); + return cometError(vm, "SocketError", errMsg); + } + + return Success(int64_t, objectPtr, 0); +} + +ResultType(int64_t, objectPtr) impl_accept(int64_t* args, CometVM* vm) { + CometObject* self = (CometObject*)args[0]; + + int fd = self->fields[0]; + + struct sockaddr_in clientAddr; + size_t clientAddrSize = sizeof(clientAddr); + + int clientSocket = accept(fd, (struct sockaddr*)&clientAddr, (socklen_t*)&clientAddrSize); + if (clientSocket < 0) { + char* errMsg = strerror(errno); + return cometError(vm, "SocketError", errMsg); + } + + CometSerializedStruct* socketStruct = cometVMGetStruct(vm, "Socket"); + CometObject* clientCometSocket = cometCreateObject(socketStruct); + + clientCometSocket->fields[0] = clientSocket; + clientCometSocket->fields[1] = clientAddr.sin_port; + + return Success(int64_t, objectPtr, (int64_t)clientCometSocket); +} + ResultType(int64_t, objectPtr) impl_recv(int64_t* args, CometVM* vm) { int amount = cometArgInt(args[0]); CometObject* self = (CometObject*)args[1]; @@ -95,7 +158,7 @@ ResultType(int64_t, objectPtr) impl_close(int64_t* args, CometVM* vm) { int fd = self->fields[0]; int result = close(fd); - if (result < 0) { + if (result != 0) { char* errMsg = strerror(errno); return cometError(vm, "IOError", errMsg); } @@ -109,15 +172,30 @@ void defineSocketStruct(CometEnvironment* env, CometTypeMap* typeMap) { CometStruct* socketStruct = cometDefineStruct(env, "Socket", NULL); + CometType socketStructType = { + .typeKind = COMET_STRUCT, + .structType = socketStruct + }; + List(StructField) fields = newList(StructField); append(fields, cometCreateField("fd", cometTypeInt, FIELD_PRIVATE)); append(fields, cometCreateField("family", cometTypeSmall, FIELD_READ_ONLY)); + /// METHODS /// List(externalMethodPtr) methods = newList(externalMethodPtr); + // client append(methods, cometDefineMethod(env, "connect", socketStruct, FIELD_PUBLIC, cometTypeVoid, 2, false, cometTypeString, cometTypeInt)); + + // server + append(methods, cometDefineMethod(env, "bind", socketStruct, FIELD_PUBLIC, cometTypeVoid, 2, false, cometTypeString, cometTypeInt)); + append(methods, cometDefineMethod(env, "listen", socketStruct, FIELD_PUBLIC, cometTypeVoid, 1, false, cometTypeInt)); + append(methods, cometDefineMethod(env, "accept", socketStruct, FIELD_PUBLIC, socketStructType, 0, false)); + + // general append(methods, cometDefineMethod(env, "recv", socketStruct, FIELD_PUBLIC, cometTypeString, 1, false, cometTypeInt)); append(methods, cometDefineMethod(env, "send", socketStruct, FIELD_PUBLIC, cometTypeVoid, 1, false, cometTypeString)); append(methods, cometDefineMethod(env, "close", socketStruct, FIELD_PUBLIC, cometTypeVoid, 0, false)); + /// END OF METHODS /// cometSetStructFieldsAndMethods(socketStruct, fields, methods); cometDefineConstructor(env, socketStruct, 3, false, familyEnum, typeEnum, cometTypeInt);