From 9443e70f54e13cc6ef2c678894d1af4f8cc5c0c4 Mon Sep 17 00:00:00 2001 From: William Adams Date: Mon, 29 Jul 2013 16:06:36 -0700 Subject: [PATCH] new file: UdpEchoClient.lua new file: UdpEchoServer.lua --- src/bin/tinn.exe | Bin 1684480 -> 1686528 bytes src/computicle/IOCPSocket.lua | 143 +++++++++++++++++++---- src/net/SocketServer.lua | 2 +- src/win32/apiset/WinCon.lua | 7 +- src/win32/apiset/core_console_l1_1_0.lua | 18 ++- src/win32/apiset/ws2_32.lua | 29 ++++- tests/LineServer.lua | 13 ++- tests/SToken.lua | 23 +++- tests/UdpEchoClient.lua | 91 +++++++++++++++ tests/UdpEchoServer.lua | 64 ++++++++++ tests/test_SToken.lua | 13 +++ 11 files changed, 366 insertions(+), 37 deletions(-) create mode 100644 tests/UdpEchoClient.lua create mode 100644 tests/UdpEchoServer.lua diff --git a/src/bin/tinn.exe b/src/bin/tinn.exe index 4e61c3636f0467cac846992e14570fd9de6efb3e..36e30e0970029c94e7637c0a0eeda5a0c82cd348 100644 GIT binary patch delta 5451 zcmeI$dvp_39tZH>y?Hc`naO1GXoFS5Beczg(n@M+7b8_*i$E>VT|Jwh}IiJkE zGxz@H&Tl4@xzl=de(N{$+t~oy^nGY;Bb0_hYrDRcn;d(EY_z!ceH!xF4V&?3#PyrD21UQ!};|d>V>0l5O%Nk#Aq7| z8=(zWz+$)q8etwxfl?@dp^yyyn9&~d z&^0KGhRY!UD=^a3$Aa?NM=@G>3--aY@C2-e#jyJ!3>3?GPywSL00Y1RUp?ZX58zGM z4O?L?EQeO8kKt<`Oo1^FgrVRD6MXfshYmwG?1IhE4l7_WG{N;y1y?~327v+uCo#Z7 z@ESY|8(HgU)pw`FG?@ifz=B!L3u+wN^${ zW#FxO21exuP7>)+XRQvsj#L9tv4IReBO^IOPpS!Z6F2$HI+86q3Ym0tg@N-NY|qOe z%E5LSzldTp+FG%+a;r};kSwCDRmWuk>qSPzV$3Lp%m$u^#;TR0VTM%}(Lpd#NZ?!+ z(Md9rY|9{7Hj!$_HaoZb6f?;VMj<Nb^(cp|7H-A>ssz?r zC5Wx6fPDy7AtW#!6a~_c6-25MGg^b9NIprzjsyycI+lmg$&x_hFyf$K!^j16lm%JB zKy4Vg&1fr@?dFhR(3gwx%C5Zl&X=xDOwRRW4RGENiB?oc7u*(^+E8;-Bq~jxS~fLO zAFgWX$o|_I7Hdb!Gm-L&pQlwu8bb#Ck7?{rGa=0!DMmK>Qi_yY;l~u}(=wP!H6hg; z14bXDy8nm`eFHBRjX1a%0!c`#4QZ8;Ry)$FprewZ_#7sZok**K^f|1g;vQD)%y9aU zQrV5PIXT_pL42ejqWF@^QQI&+OB7;7gi2aBZl8{viS)Gm* z<0PaNjbuqgN1G_ykX9LKmGyG5T{eeAgFYyuv)xXzf&dP*b=oK-8(6u-iS`)wussSA zJ0((c+qkBNn@hd%!+#wZU)WW_-0{PE-Pu1s3vycHcu$vV{v<<3R;r+Ig017D60f+O}x}m$M z)Bk5pS$c;ucV#4Ulh(VhLs?>brDGDV60(=o)iu;;+mim{!f8W7@`|RVgH8(|f&{kY zpwsfT7sb|>aWauWgM;`x@G+bR;yjOW>d!TPD4g@udGP6xcO7REF`OS=YyUb!-@5)X zen8k>tjj=K6Yhyv8qJiGasEQcfP0{h@gkiC=QMr0oNDlWT7%V+y^?h#CrkFNM)Tac z&Czg8bzNQZg42E`OElMnBlCsptD7Uy=5YMTr>>>Ge0$QDuS6@aDkGhl>Byq$a9!v~ zC+l%h;$E#9Q8zN9F9Sb(6OPZQqbqTWXpgm~wz|pdH`i1*M@{vS+mmbVQkLk2S06)| z;dF?LA7`Y_cy8k95gunkoaqpfx7@8*ZTnE$mTK42R}T6=!VkbtRjR(VzyHU5>#O`o zcwf9vC=}}pnCf&iEx@s~@~3I#&(g}r)5<5($|tpQYLK6&$~dr7IIz<=urF{xXZ(d~ zFP2~WN2p&@tT6Bul?J|1`;YWn9L-q@s;4Lz_!gaYeVzM9`(4^j&ZU*VPb;5KD_=+} z6H8?-$4{)t&r(aoanzFr^TAu5#m@;Pi0l;+i`zcOe;%Tx$pejv`#V`;a6CpYG?iFak9dIgZYNJ zSV>@*S{QJnoY`0I&sG+8lFF8h1IR**)B(uaKs;K^0f?E6m=_`Ddr1AoTI@>^`x54h z4fCc29H<2xfPe$FfCIFEgS3Ey5zvQ#L$p9S2s9J}OOKPQ#Tkq^xmujTTAVyBjvsMU z_N$++@_^RKk4^!tQ>xK0=2P=oiBldA)n{n+8Crd&R-dWWXKD3WT79-wpPgu2sSLm5r{@Ymd%{Tnk4rweQpx0r zeXEq&{E#y_@Ihs^!M312YDxPaOzd5w+?m+FOOY@3d+Qog|7!t@7oUlh<14DPHFc5t z#N;(fb#l>K<*YmTyY0$5&ct;uDXaXc0bKQ)adU5u3UlW!s1HY4EOY1LCWAXPS^KwH zqYE1&4fB&OKT1&-~cDMzzvznngdz)JTC6Rv?kTH?~^#u;<>%_p|$jVDeCoxzv)hbxusaXvG5q-M`FfpL3$*2a7z5O|c)Q_nV*c z^j(n~aJ{9>z@>HM3CuhH>>=+UqTcWD;5@}aM^7-Ca~9Vwp7VC$xnjtZME7-~{Vfh! zw#`Wb?#ba!C+S~t(xz@F&Ea|)IYgkqRRReSfev19Qt&p3oCX)k3#AyH!}KGJ2l19{ zMm=6eT|*h2%f~~>Ux;d7B^q;#s7rBC?Q#4bJTBVP%xOjooWrwfo{bJxxX5{(i#o$D zYFXr>=zT7lvCKtBq5_%La>`!K>G(sOHb2VAxejrjcG2hwZqjeybaX?E)2<3P)#6FX zTjeIx7Dmfvx~XkDo?`EC(!G@*+|;rkGfF%U>;J*%n>}vo9b~6Q%;ds7ZW=NvlX_~isAnuPIzE%Suftn}*vE_l zXB5iXh@)NLpgT<>c`=1(%N0pKTqI{mq-A47TGArY(cg=-;%<=w4~R4)f$}DiD));t zuN%|I*F`#Y60?WXB5mdp)n!SPdx=EZm`5C>+CS!lP67jS?OD&`GfZ zOt6lNda9c!Q191HGA)s4UIwGqLQaRyO62vrDEBf>b3WqKK7!F^%wNvk;v#*Ei#Fbi zlt0F3Ovpx^2^X#h9WA?uQ|%-hIX`z%-P<62rofG`7}miycp2V<6TmimC=*l&ZH{^9S`@<24EMqY=!Dmx2fhP&i-&UI z3aEkxxCh$cX?PLdf@45iu>(-y3aErI+zR)=D%b)qz=0UP-iKb$KZCb0PzYmT7Tf|$ z;Zf*-{qRpX4(GtJ%|kx89LB>exC!or`(XogLN^?SGoas&0fHZ5rTCfxH^A>;IkZC( zUWQM=@T`Z1z-S0V4A#Q)a1c&_y#p^|paL4?!e2mhf&xH zFTepf0;k|S$UE_B2#R3>%zRMh%4oF_gk+mZ? YkK8u$_{dWu<&r>2K}k}1%yUxy4>oH%c>n+a delta 4237 zcmeI#eN}G~&$w^IM)m38wdokDH zxSo|Qc6SJLkk~}DBJ=HtHP%tr<5KJPYM!>O#A3~oibXP7u|?ePg}dj>+5h(c?m3@% ze$T!4`Q7Jv?uGl@>VdNA?y?p!+PSdrUKm>!q=*x-Koxi7)sGfM>au1HIS!ztPQ(2A zT_U-Dhe(rcf%;S8!Pspn8W7;QW9vQAE1K$yWSVGh-z0yrRz}ygfAjDdlWY#uE0s+$ zy{^8kG88osxF0750`;|3NpVlzC_0Kd)=|g$F_~Z2K5zXi((m9Uhn~^UOCL}NwNV2- zLJ!a!nnYtsq24A9U(y-!u)V(RZPajp^#*#9Hd7U?rXtFt36x5SWTxI7njc*|cwstC zC+RTlr4|a%W?D_lsE7(^Hch1oluDz?N@f~hM|$ZZeL`pGG@YO$)JlyMpqfU%h7AnL zsf>#0BzvZB(;0gxks_%-sNn*ANN><#>TO_0Sq5kmt)XI?N7HFM*-29Gb`77>n{ z(X)R31ZXo=Q3(~%9GXhw$wGtMH1tp>ouQL-m|E#++CmjnLJMd%Wzx;0&=5O%fzDC~ z9imp6w4Fb-w2{`(gH%9yG>KBlMUm8Buc5oXeZq#cpSC~o*VjbMsVEcTFb~UuyLQSM z!TI|gO7Qnr9qH|7-ia2rOrSbHQUXdv>59@-kCe7s-kU7j?|R?;`iy1)86hHI&E@fU zNEDhPs`WV6Bw#fQWmI*xlyI9&m?@?3>c^!y`0{pfcXDib#j15x_IuXNTCt+E zylVdPisfrnqqcQQP>>`OnJI!IDT<;ghGHo$G$p9~9TA`yY;VBU~b3m&(sYVbgx zl4#Bs5+UCeZ?<8yi}b3C2M_2|dW8^`qc)8RPV^BM2D2Zdg9^~gD0!}|+8oRi@; z{|IYyAuRqpEWS7r`-dBR5q99qu=r9~+-<~qC%@8TcJgaX_Vggj`wgah|LMu{_OiU} zne6=*S-w6@_g(Q$_kQQe@$_>r-y_@mHL`vEY-<{Bt9RD#_WmpEB3HxWfw1^mSo}j+ z{O{p7%>$9+83aovz7DG=f)^X)#jf+Xez76_m^sIDgQXQYJU@H5jqr;!PYQQPmV%{; zrDSPlX=WK=+?Gf&GU7D*AjE*>rq)sLs#iTCb_9cpGULU7lGcJ(C z3yfyYnj#WY1PePWubmlq;LD7CmEMB2U>v?JOfg>8$&s*qcj@baK;12_A6FJXt}On~l||_AueHt5{{JqLJ6korCV^H%4IeG*POjc| zX-F9h`1IB@K` z35{bE)ZVUO%`yebfCHK378G1}K&iC&Q5z%BA1@G{C{UFwuz0LME&sI^9tT#w1$=Ok zJ&JQ;;1XcAJCX9R#L-HL?yJDYaq&>*I#ICDiN0bd4plm_uiA;g7ANw`6|CGQv9V5~ zpiy!y&9dH!mfcP~cBcy^f0W37)-TaN$Ay7GU~z#9jco!Q_p-iEAiu(e9*YgtkGPO} zK;p;-7t)(t$h6wfz2AwhBpU{fNMvr(N2Xy3}~FX+lAa8E?;3;Ole1yvc$-DbVGU_^984#feVTWJnzA z;z%cQbg}WsUhTw;awj@BIT5{6Aa80s`u^bL^B~bvEm1Nz9tD@2Sa~)c9b>FWooYqN z?N&HuSy8^wijDWXkoUM1ffngUb*n`AL4lfAd0&nRBp&AjRHGpI1sA$rbRlJq4XHsJ zQnuOA@MnoH_@G`P({2qKWzuX~L~Cg?HPK;ui@N9^l1 z@~`I4W(v}NIzeaX5?!NFd-;`2g;Y)rbdcVpugLrorWgS3fS=ym#>ZqUv9G~7mu zXgxL19t!Q_C+Ry3KBdcK+RuMFltL3Ij~39+=?SW(-E@@RrSo)|LXXk! zsEJ;p6Lg+T2Q{S894a|DgWshLg7hN2M(@*S)KBI^dKbb69RsaA1 diff --git a/src/computicle/IOCPSocket.lua b/src/computicle/IOCPSocket.lua index cc0cb02..7a1b4ae 100644 --- a/src/computicle/IOCPSocket.lua +++ b/src/computicle/IOCPSocket.lua @@ -205,14 +205,14 @@ IOCPSocket.setKeepAlive = function(self, keepalive, timeout, interval) return success, err end - IOCPSocket.setNoDelay = function(self, nodelay) - local oneint = ffi.new("int[1]"); - if nodelay then - oneint[0] = 1 - end +IOCPSocket.setNoDelay = function(self, nodelay) + local oneint = ffi.new("int[1]"); + if nodelay then + oneint[0] = 1 + end - return WinSock.setsockopt(self:getNativeSocket(), IPPROTO_TCP, TCP_NODELAY, oneint, ffi.sizeof(oneint)) - end + return WinSock.setsockopt(self:getNativeSocket(), IPPROTO_TCP, TCP_NODELAY, oneint, ffi.sizeof(oneint)) +end IOCPSocket.setNonBlocking = function(self, nonblocking) local oneint = ffi.new("int[1]"); @@ -223,23 +223,23 @@ IOCPSocket.setNonBlocking = function(self, nonblocking) return WinSock.ioctlsocket(self:getNativeSocket(), FIONBIO, oneint); end - IOCPSocket.setReuseAddress = function(self, reuse) - local oneint = ffi.new("int[1]"); - if reuse then - oneint[0] = 1 - end +IOCPSocket.setReuseAddress = function(self, reuse) + local oneint = ffi.new("int[1]"); + if reuse then + oneint[0] = 1 + end - return WinSock.setsockopt(self:getNativeSocket(), SOL_SOCKET, SO_REUSEADDR, oneint, ffi.sizeof(oneint)) - end + return WinSock.setsockopt(self:getNativeSocket(), SOL_SOCKET, SO_REUSEADDR, oneint, ffi.sizeof(oneint)) +end - IOCPSocket.setExclusiveAddress = function(self, exclusive) - local oneint = ffi.new("int[1]"); - if exclusive then - oneint[0] = 1 - end +IOCPSocket.setExclusiveAddress = function(self, exclusive) + local oneint = ffi.new("int[1]"); + if exclusive then + oneint[0] = 1 + end - return WinSock.setsockopt(self:getNativeSocket(), SOL_SOCKET, SO_EXCLUSIVEADDRUSE, oneint, ffi.sizeof(oneint)) - end + return WinSock.setsockopt(self:getNativeSocket(), SOL_SOCKET, SO_EXCLUSIVEADDRUSE, oneint, ffi.sizeof(oneint)) +end --[[ Reading Socket Options @@ -474,6 +474,55 @@ IOCPSocket.send = function(self, buff, bufflen) return bytes; end +IOCPSocket.sendTo = function(self, lpTo, iTolen, buff, bufflen) + if lpTo == nil then + return false; + end + + + bufflen = bufflen or #buff + + local lpBuffers = ffi.new("WSABUF", bufflen, ffi.cast("char *",buff)); + local dwBufferCount = 1; + local lpNumberOfBytesSent = nil; + local dwFlags = 0; + local lpOverlapped = self:createOverlapped(ffi.cast("uint8_t *",buff), bufflen, SocketOps.WRITE); + local lpCompletionRoutine = nil; + + local status = ws2_32.WSASendTo(self:getNativeSocket(), + lpBuffers, + dwBufferCount, + lpNumberOfBytesSent, + dwFlags, + ffi.cast("const struct sockaddr *", lpTo), + iTolen, + ffi.cast("OVERLAPPED *",lpOverlapped), + lpCompletionRoutine); + + + -- Do the following if we want to handle + -- immediate success + if status == 0 then + --print("#### IOCPSocket, WSASend STATUS == 0 ####") + -- return the number of bytes transferred + --return lpNumberOfBytesSent[0]; + else + local err = ws2_32.WSAGetLastError(); + if err ~= WSA_IO_PENDING then + print(" IOCPSocket.send, ERROR: ", err); + return false, err; + end + end + + local key, bytes, ovl = IOProcessor:yieldForIo(self, SocketOps.WRITE, lpOverlapped.opcounter); + +--print("WSASEND: ", key, bytes, ovl); + + -- BUGBUG + return bytes; +end + + IOCPSocket.receive = function(self, buff, bufflen) @@ -524,6 +573,58 @@ IOCPSocket.receive = function(self, buff, bufflen) end +IOCPSocket.receiveFrom = function(self, lpFrom, fromLen, buff, bufflen) + + local lpBuffers = ffi.new("WSABUF", bufflen, buff); + local dwBufferCount = 1; +-- local lpNumberOfBytesRecvd = ffi.new("DWORD[1]"); + -- if we're going to use io completion ports, then + -- the numberOfBytesRecvd MUST be == nil + local lpNumberOfBytesRecvd = nil; + local lpFlags = ffi.new("DWORD[1]"); + local lpOverlapped = self:createOverlapped(buff, bufflen, SocketOps.READ); + local lpCompletionRoutine = nil; + local lpFromlen = ffi.new("DWORD[1]", fromLen); + + local status = ws2_32.WSARecvFrom(self:getNativeSocket(), + lpBuffers, + dwBufferCount, + lpNumberOfBytesRecvd, + lpFlags, + ffi.cast("struct sockaddr *", lpFrom), + lpFromlen, + ffi.cast("OVERLAPPED *",lpOverlapped), + lpCompletionRoutine); + + +--print("IOCPSocket.receive, WSARecv(), STATUS: ", status); + + -- if the return value is == 0, then the transfer + -- to the network stack has already completed, + -- but the completion notification has not necessarily + -- happened, so treat it the same as PENDING + if status == 0 then + --print("#### IOCPSocket.WSARecv, STATUS == 0 ####"); + + --return lpNumberOfBytesRecvd[0]; + else + -- didn't get bytes immediately, so see if it's a 'pending' + -- or some other error + local err = ws2_32.WSAGetLastError(); + + if err ~= WSA_IO_PENDING then + print("IOCPSocket.WSARecv, ERROR: ", err); + return false, err; + end + end + + local key, bytes, ovl = IOProcessor:yieldForIo(self, SocketOps.READ, lpOverlapped.opcounter); + +print("WSARecvFrom: ", key, bytes, ovl); + + return bytes; +end + return IOCPSocket; \ No newline at end of file diff --git a/src/net/SocketServer.lua b/src/net/SocketServer.lua index abb5d97..e2f36a3 100644 --- a/src/net/SocketServer.lua +++ b/src/net/SocketServer.lua @@ -49,7 +49,7 @@ end SocketServer.handleAccepted = function(self, sock) ---print("SocketServer.handleAccepted(): ", sock); +print("SocketServer.handleAccepted(): ", sock); if self.OnAccept then --print("CALLING self.OnAccept") diff --git a/src/win32/apiset/WinCon.lua b/src/win32/apiset/WinCon.lua index b97a03d..dd7d36e 100644 --- a/src/win32/apiset/WinCon.lua +++ b/src/win32/apiset/WinCon.lua @@ -2,9 +2,8 @@ local ffi = require("ffi"); local NOGDI = true; -ffi.cdef[[ -typedef int16_t SHORT; -]] +local basetsd = require("basetsd"); + ffi.cdef[[ typedef struct _COORD { @@ -245,7 +244,7 @@ static const int ENABLE_WRAP_AT_EOL_OUTPUT = 0x0002; -typedef BOOL ( *PHANDLER_ROUTINE)(DWORD CtrlType); +typedef BOOL (__stdcall *PHANDLER_ROUTINE)(DWORD CtrlType); typedef struct _CONSOLE_READCONSOLE_CONTROL { ULONG nLength; diff --git a/src/win32/apiset/core_console_l1_1_0.lua b/src/win32/apiset/core_console_l1_1_0.lua index 472a3d2..e0fb749 100644 --- a/src/win32/apiset/core_console_l1_1_0.lua +++ b/src/win32/apiset/core_console_l1_1_0.lua @@ -86,4 +86,20 @@ WriteConsoleW(HANDLE hConsoleOutput, LPVOID lpReserved); ]] -return k32Lib; +return { + AllocConsole = k32Lib.AllocConsole, + GetConsoleCP = k32Lib.GetConsoleCP, + GetConsoleMode = k32Lib.GetConsoleMode, + GetConsoleOutputCP = k32Lib.GetConsoleOutputCP, + GetNumberOfConsoleInputEvents = k32Lib.GetNumberOfConsoleInputEvents, + PeekConsoleInputA = k32Lib.PeekConsoleInputA, + ReadConsoleA = k32Lib.ReadConsoleA, + ReadConsoleInputA = k32Lib.ReadConsoleInputA, + ReadConsoleInputW = k32Lib.ReadConsoleInputW, + ReadConsoleW = k32Lib.ReadConsoleW, + SetConsoleCtrlHandler = k32Lib.SetConsoleCtrlHandler, + SetConsoleMode = k32Lib.SetConsoleMode, + WriteConsoleA = k32Lib.WriteConsoleA, + WriteConsoleW = k32Lib.WriteConsoleW, +} + diff --git a/src/win32/apiset/ws2_32.lua b/src/win32/apiset/ws2_32.lua index 4ad5694..6a8bfd6 100644 --- a/src/win32/apiset/ws2_32.lua +++ b/src/win32/apiset/ws2_32.lua @@ -429,7 +429,16 @@ typedef struct __WSABUF { char * buf; } WSABUF, *LPWSABUF; ]] +WSABUF = ffi.typeof("WSABUF"); +WSABUF_mt = { + __new = function(ct, buf, len) + return ffi.new(ct, len, ffi.cast("char *", buf)); + end, + + __index = { + }, +} -- -- MSTcpIP.h -- @@ -988,6 +997,18 @@ int WSARecv( LPWSAOVERLAPPED lpOverlapped, void* lpCompletionRoutine); +int +WSARecvFrom( + SOCKET s, + LPWSABUF lpBuffers, + DWORD dwBufferCount, + LPDWORD lpNumberOfBytesRecvd, + LPDWORD lpFlags, + struct sockaddr * lpFrom, + LPINT lpFromlen, + LPWSAOVERLAPPED lpOverlapped, + LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine); + int WSASend(SOCKET s, LPWSABUF lpBuffers, @@ -1321,10 +1342,10 @@ WSApSetPostRoutine = Lib.WSApSetPostRoutine, --]] WSARecv = Lib.WSARecv, + WSARecvFrom = Lib.WSARecvFrom, --[[ WSARecvDisconnect = Lib.WSARecvDisconnect, -WSARecvFrom = Lib.WSARecvFrom, WSARemoveServiceClass = Lib.WSARemoveServiceClass, WSAResetEvent = Lib.WSAResetEvent, --]] @@ -1334,10 +1355,12 @@ WSAResetEvent = Lib.WSAResetEvent, --[[ WSASendDisconnect = Lib. WSASendMsg = Lib. -WSASendTo = Lib. -WSASetBlockingHook = Lib. --]] + WSASendTo = Lib.WSASendTo, + +-- deprecated: WSASetBlockingHook = Lib. + WSASetEvent = Lib.WSASetEvent, --[[ diff --git a/tests/LineServer.lua b/tests/LineServer.lua index 85b452b..b72e3a1 100644 --- a/tests/LineServer.lua +++ b/tests/LineServer.lua @@ -19,7 +19,18 @@ local OnAccept = function(param, sock) print("LINE: ", line); -- write the line back out to the socket - socket:send(line, #line); + local body = ""..line.."\r\n" + local content = [[ +HTTP/1.1 200 OK +Connection: close + +]]..body + +print("CONTENT"); +print(content); + + socket:send(content, #content); + socket:closeDown(); --socket:send(buff, bytesread); end diff --git a/tests/SToken.lua b/tests/SToken.lua index 03a8561..28e0fe0 100644 --- a/tests/SToken.lua +++ b/tests/SToken.lua @@ -34,17 +34,28 @@ local SToken_mt = { end, __eq = function(self, other) - print("SToken:__eq()"); - local maxbytes = math.min(self.Length, other.Length); + -- print("SToken:__eq(): ", type(self), type(other)); + + local otherData = ffi.cast("const uint8_t *", other); + local otherLength = #other; + local otherOffset = 0; + + if type(other) == "string" then + else + otherOffset = other.Offset; + end + + + local maxbytes = math.min(self.Length, otherLength); for i=0,maxbytes-1 do - if self.Data[self.Offset+i] > other.Data[other.Offset+i] then - print("RETURN 1.0"); + if self.Data[self.Offset+i] > otherData[otherOffset+i] then + --print("RETURN 1.0"); return false end - if self.Data[self.Offset+i] < other.Data[other.Offset+i] then - print("RETURN 2.0"); + if self.Data[self.Offset+i] < otherData[otherOffset+i] then + --print("RETURN 2.0"); return false end end diff --git a/tests/UdpEchoClient.lua b/tests/UdpEchoClient.lua new file mode 100644 index 0000000..27aad21 --- /dev/null +++ b/tests/UdpEchoClient.lua @@ -0,0 +1,91 @@ +local ffi = require "ffi" + +local IOProcessor = require("IOProcessor"); +local IOCPSocket = require("IOCPSocket"); +local ws2_32 = require("ws2_32"); +local SocketUtils = require("SocketUtils"); + +local StopWatch = require("StopWatch"); + +local hostname = "localhost" +local serviceport = 9090 + + +local argv = {...} +local argc = #argv + +local EchoRequest = function(socket, addr, addrlen) + -- fill the buffer with current time + local datestr = os.date("%c"); + + local bytessent, err = socket:sendTo(addr, addrlen, datestr, #datestr); + +print("bytessent: ", bytessent, err); + + if not bytessent then + print("sendTo ERROR: ", bytessent, err); + return false, err; + end + + local bufflen = 1500; + local buff = ffi.new("uint8_t[?]", bufflen); + + local fromAddr = sockaddr_in(); + local fromLen = ffi.sizeof(fromAddr); + + local bytesreceived, err = socket:receiveFrom(fromAddr, fromLen, buff, bufflen); + + if not bytesreceived then + return false, err; + end + + if bytesreceived > 0 then + print("RECEIVED: ", bytesreceived); + return ffi.string(buff, bytesreceived); + end + + return string.format("bytesreceived == %d", bytesreceived); +end + + + +loop = function() + local sw = StopWatch(); + + local iterations = tonumber(argv[1]) or 1; + --print("iterations: ", iterations); + + + -- create the client socket + local socket, err = IOCPSocket:create(AF_INET, SOCK_DGRAM, 0); + + if not socket then + print("Socket Creation Failed: ", err); + return nil, err; + end + + -- create the address to the server + local addr, err = SocketUtils.CreateSocketAddress(hostname, serviceport) + local addrlen = ffi.sizeof(addr); + + + + local transcount = 0; + + for i=1,iterations do + local dtc, err = EchoRequest(socket, addr, addrlen); + + if dtc then + transcount = transcount + 1; + print(transcount, dtc, transcount/sw:Seconds()); + else + print("Error: ", i, err); + end + collectgarbage(); + end + + print("Transactions: ", transcount, transcount/sw:Seconds()); +end + +run(loop); + diff --git a/tests/UdpEchoServer.lua b/tests/UdpEchoServer.lua new file mode 100644 index 0000000..571bbc0 --- /dev/null +++ b/tests/UdpEchoServer.lua @@ -0,0 +1,64 @@ +local ffi = require("ffi"); + +local IOProcessor = require("IOProcessor"); +local IOCPSocket = require("IOCPSocket"); +local ws2_32 = require("ws2_32"); + +--IOProcessor:setMessageQuanta(5); +local serverport = 9090; + + +local createServerSocket = function(port) + local port = port or serverport; + local socket, err = IOCPSocket:create(AF_INET, SOCK_DGRAM, 0); + + if not socket then + print("create socket ERROR: ", err); + return nil, err; + end + + local addr = sockaddr_in(port); + local addrlen = ffi.sizeof(addr); + + success, err = socket:bind(addr,addrlen) + + if not success then + return false, err; + end + + return socket; +end + +-- The primary application loop +local loop = function() + local bufflen = 1500; + local buff = ffi.new("uint8_t[?]", bufflen); + local from = sockaddr_in(); + local fromLen = ffi.sizeof(from); + + local socket, err = createServerSocket(serverport); + + if not socket then + print("createServerSocket Error: ", err); + return false, err; + end + + while true do + local bytesread, err = socket:receiveFrom(from, fromLen, buff, bufflen); + + if not bytesread then + print("receiveFrom ERROR: ", err) + return false, err; + end + + print("BYTESREAD: ", bytesread, from); + + print(ffi.string(buff, bytesread)); + + -- echo back to sender + local bytessent, err = socket:sendTo(from, fromLen, buff, bufflen); + --collectgarbage(); + end +end + +run(loop); diff --git a/tests/test_SToken.lua b/tests/test_SToken.lua index fb30dac..5b587bb 100644 --- a/tests/test_SToken.lua +++ b/tests/test_SToken.lua @@ -16,6 +16,7 @@ local beg2, end2 = testVector:find("words"); local len2 = end2-beg2+1 local tok3 = SToken(testVector, beg2-1, len2); +local function test_Token() print("Token: ", tok1); print("Token Length: ", #tok1); print("Tok1 == Tok2: ", tok1 == tok2); @@ -23,3 +24,15 @@ print("Tok1 == Tok2: ", tok1 == tok2); print("Token3: ", tok3); print("Token 3 Len: ", #tok3); print("tok1 == tok3: ", tok1 == tok3); +end + +local function test_StringCompare() + print("SToken string compare") + print("tok1 == 'this'", tok1 == "this"); + print("'this' == tok1", 'this' == tok1); + print("tok1 == 'flipper'", tok1 == "flipper") +end + + +--test_Token(); +test_StringCompare();