diff --git a/samples/client.noja b/samples/client.noja index 241aec1..b5c11e8 100644 --- a/samples/client.noja +++ b/samples/client.noja @@ -23,4 +23,14 @@ if net.connect(fd, { sin_family: net.AF_INET, sin_port: net.htons(port), sin_add return none; } -print('Connected!\n'); \ No newline at end of file +print('Connected!\n'); + +buffer = newBuffer(16); + +buffer[0] = 9; +buffer[1] = 7; +buffer[2] = 255; + +n = net.send(fd, buffer, 0); + +print('Sent ', n, ' bytes: ', buffer, '\n'); \ No newline at end of file diff --git a/samples/server.noja b/samples/server.noja index c4c8aac..7670ea8 100644 --- a/samples/server.noja +++ b/samples/server.noja @@ -22,6 +22,8 @@ if net.listen(fd, backlog) != 0: return none; } +buffer = newBuffer(16); + while true: { client_addr = {}; @@ -34,5 +36,20 @@ while true: print('client_fd = ', client_fd, '\n'); print('client_addr = {', client_addr, '}\n'); - # ..continue.. + do + { + n = net.recv(client_fd, buffer, 0); + + if n < 0: + print('Warning! Failed to read from socket!\n'); + else if n == 0: + { + # Client disconnected. + } + else + { + print('Received ', n, ' bytes: ', buffer, '\n'); + } + } + while n > 0; } \ No newline at end of file diff --git a/src/o_net_builtins.c b/src/o_net_builtins.c index 12f3972..cb4cb66 100644 --- a/src/o_net_builtins.c +++ b/src/o_net_builtins.c @@ -22,6 +22,8 @@ static Object *bin_htonl(Runtime *runtime, Object **argv, unsigned int argc, Err static Object *bin_ntohl(Runtime *runtime, Object **argv, unsigned int argc, Error *error); static Object *bin_htons(Runtime *runtime, Object **argv, unsigned int argc, Error *error); static Object *bin_ntohs(Runtime *runtime, Object **argv, unsigned int argc, Error *error); +static Object *bin_send(Runtime *runtime, Object **argv, unsigned int argc, Error *error); +static Object *bin_recv(Runtime *runtime, Object **argv, unsigned int argc, Error *error); typedef struct { @@ -59,6 +61,22 @@ static Object *select_(Object *self, Object *key, Heap *heap, Error *err) switch(PAIR(n, s[0])) { + case PAIR(4, 's'): + { + if(!strcmp(s, "send")) + return Object_FromNativeFunction(bm->runtime, bin_send, 3, heap, err); + + return NULL; + } + + case PAIR(4, 'r'): + { + if(!strcmp(s, "recv")) + return Object_FromNativeFunction(bm->runtime, bin_recv, 3, heap, err); + + return NULL; + } + case PAIR(10, 'I'): { if(!strcmp(s, "INADDR_ANY")) @@ -669,5 +687,47 @@ static Object *bin_accept(Runtime *runtime, Object **argv, unsigned int argc, Er return NULL; } - return Object_FromInt(r, heap, error); + return Object_FromInt(r, heap, error); +} + +static Object *bin_send(Runtime *runtime, Object **argv, unsigned int argc, Error *error) +{ + assert(argc == 3); + + Heap *heap = Runtime_GetHeap(runtime); + + int sockfd = Object_ToInt(argv[0], error); + if(error->occurred) return NULL; + + int size; + void *addr = Object_GetBufferAddrAndSize(argv[1], &size, error); + if(addr == NULL) return NULL; + + int flags = Object_ToInt(argv[2], error); + if(error->occurred) return NULL; + + ssize_t r = send(sockfd, addr, size, flags); + + return Object_FromInt(r, heap, error); +} + +static Object *bin_recv(Runtime *runtime, Object **argv, unsigned int argc, Error *error) +{ + assert(argc == 3); + + Heap *heap = Runtime_GetHeap(runtime); + + int sockfd = Object_ToInt(argv[0], error); + if(error->occurred) return NULL; + + int size; + void *addr = Object_GetBufferAddrAndSize(argv[1], &size, error); + if(addr == NULL) return NULL; + + int flags = Object_ToInt(argv[2], error); + if(error->occurred) return NULL; + + ssize_t r = recv(sockfd, addr, size, flags); + + return Object_FromInt(r, heap, error); } \ No newline at end of file diff --git a/src/objects/o_buffer.c b/src/objects/o_buffer.c index 22d2a2b..7ed68e8 100644 --- a/src/objects/o_buffer.c +++ b/src/objects/o_buffer.c @@ -48,6 +48,21 @@ Object *Object_NewBuffer(int size, Heap *heap, Error *error) return (Object*) obj; } +void *Object_GetBufferAddrAndSize(Object *obj, int *size, Error *error) +{ + if(obj->type != &t_buffer) + { + Error_Report(error, 0, "Not a buffer"); + return NULL; + } + + BufferObject *buf = (BufferObject*) obj; + + if(size) + *size = buf->size; + return buf->body; +} + static Object *select(Object *self, Object *key, Heap *heap, Error *error) { assert(self != NULL); diff --git a/src/objects/objects.h b/src/objects/objects.h index 29b490e..aed5774 100644 --- a/src/objects/objects.h +++ b/src/objects/objects.h @@ -72,6 +72,7 @@ const Type* Object_GetType(const Object *obj); const char* Object_GetName(const Object *obj); unsigned int Object_GetSize(const Object *obj, Error *err); unsigned int Object_GetDeepSize(const Object *obj, Error *err); +void *Object_GetBufferAddrAndSize(Object *obj, int *size, Error *error); int Object_Hash (Object *obj, Error *err); Object* Object_Copy (Object *obj, Heap *heap, Error *err); Object* Object_Call (Object *obj, Object **argv, unsigned int argc, Heap *heap, Error *err);