From 73450092f27ad3572bca0ed159408f567230bf41 Mon Sep 17 00:00:00 2001 From: ValKmjolnir Date: Thu, 23 Mar 2023 00:09:51 +0800 Subject: [PATCH] :sparkles: add test/jsonrpc.nas and fix bug bug: in nasocket.cpp, recv and recvfrom do not place 0 after reciving data into the buffer. --- module/nasocket.cpp | 13 +++++--- test/jsonrpc.nas | 80 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+), 5 deletions(-) create mode 100644 test/jsonrpc.nas diff --git a/module/nasocket.cpp b/module/nasocket.cpp index fc13837..92c03a9 100644 --- a/module/nasocket.cpp +++ b/module/nasocket.cpp @@ -34,7 +34,7 @@ var nas_socket(var* args,usize size,gc* ngc) { var nas_closesocket(var* args,usize size,gc* ngc) { if (args[0].type!=vm_num) - return nas_err("closesocket","\"\" should be number"); + return nas_err("closesocket","\"sd\" should be number"); #ifdef _WIN32 return var::num((double)closesocket(args[0].num())); #else @@ -149,7 +149,9 @@ var nas_recv(var* args,usize size,gc* ngc) { var res=ngc->temp=ngc->alloc(vm_hash); auto& hash=res.hash().elems; char* buf=new char[(int)args[1].num()]; - hash["size"]=var::num((double)recv(args[0].num(),buf,args[1].num(),args[2].num())); + auto recvsize=recv(args[0].num(),buf,args[1].num(),args[2].num()); + hash["size"]=var::num((double)recvsize); + buf[recvsize>=0?recvsize:0]=0; hash["str"]=ngc->newstr(buf); delete[] buf; ngc->temp=nil; @@ -171,11 +173,12 @@ var nas_recvfrom(var* args,usize size,gc* ngc) { auto& hash=res.hash().elems; char* buf=new char[(int)args[1].num()+1]; #ifdef _WIN32 - hash["size"]=var::num((double)recvfrom(args[0].num(),buf,args[1].num(),args[2].num(),(sockaddr*)&addr,&socklen)); + auto recvsize=recvfrom(args[0].num(),buf,args[1].num(),args[2].num(),(sockaddr*)&addr,&socklen); #else - hash["size"]=var::num((double)recvfrom(args[0].num(),buf,args[1].num(),args[2].num(),(sockaddr*)&addr,(socklen_t*)&socklen)); + auto recvsize=recvfrom(args[0].num(),buf,args[1].num(),args[2].num(),(sockaddr*)&addr,(socklen_t*)&socklen); #endif - buf[(int)hash["size"].num()]=0; + hash["size"]=var::num((double)recvsize); + buf[recvsize>=0?recvsize:0]=0; hash["str"]=ngc->newstr(buf); delete[] buf; hash["fromip"]=ngc->newstr(inet_ntoa(addr.sin_addr)); diff --git a/test/jsonrpc.nas b/test/jsonrpc.nas new file mode 100644 index 0000000..99e97f3 --- /dev/null +++ b/test/jsonrpc.nas @@ -0,0 +1,80 @@ +import.module.libsock; +import.stl.json; + +var jsonrpc=func(){ + var sd=nil; + return { + establish:func(ip,port) { + sd=socket.socket(socket.AF_INET,socket.SOCK_STREAM,socket.IPPROTO_IP); + if(socket.bind(sd,ip,port)<0) { + println("failed to bind socket "~sd~" at "~ip~":"~port~"."); + return 0; + } + socket.listen(sd,1); + println("[",os.time(),"] start connection at [",ip,":",port,"]"); + return 1; + }, + connect:func(ip,port) { + sd=socket.socket(socket.AF_INET,socket.SOCK_STREAM,socket.IPPROTO_IP); + while(socket.connect(sd,ip,port)<0) { + println("[",os.time(),"] failed to connect socket "~sd~" to "~ip~":"~port~", retrying."); + unix.sleep(1); + } + println("[",os.time(),"] start connection at [",ip,":",port,"]"); + return {ip:ip,sd:sd}; # get server ip and sd + }, + shutdown:func() { + println("[",os.time(),"] shutdown"); + socket.closesocket(sd); + }, + accept:func() { + return socket.accept(sd); + }, + disconnect:func(client) { + println("[",os.time(),"] [",client.ip,"] disconnected"); + return socket.closesocket(client.sd); + }, + recv:func(client){ + var data=socket.recv(client.sd,2048); + if(data.size<=0){ + println("[",os.time(),"] [",client.ip,"] closed connection"); + return nil; + } + println("[",os.time(),"] [",client.ip,"] receive ",data.str); + return data.str; + }, + send:func(client,content){ + println("[",os.time(),"] [",client.ip,"] sending ",content); + return socket.send(client.sd,content); + } + }; +}(); + +var id=1; +var args=runtime.argv(); +if (size(args)!=0) { + if (args[0]=="--server") { + jsonrpc.establish("127.0.0.1",8080); + var client=jsonrpc.accept(); + jsonrpc.send(client, JSON.stringify({jsonrpc:2.0, id:1, result:{info:"from server: first info"}})); + while(1) { + var data=jsonrpc.recv(client); + if (data!=nil) { + data=JSON.parse(data); + } else { + break; + } + jsonrpc.send(client, JSON.stringify({jsonrpc:2.0, id:data.id+1, result:{info:"from server"}})); + } + jsonrpc.disconnect(client); + } elsif (args[0]=="--client") { + var server=jsonrpc.connect("127.0.0.1",8080); + while(1) { + unix.sleep(1); + var respond=JSON.parse(jsonrpc.recv(server)); + var data=JSON.stringify({jsonrpc:2.0, id:respond.id+1, result:{info:"from client"}}); + jsonrpc.send(server, data); + } + jsonrpc.disconnect(server); + } +} \ No newline at end of file