Greetings, As most dev's know, theres no working networking module for gmod13 currently.
So here we go!
This once was EzSockets, wich then I altered to support non blocking, and altered it more to my needs, and then altered for gmod. So some things might look a bit wierd due this.
Incase anyone has some comments on my code, if i should do something another way. Please do say, as I'm not working on c++ for that long and I'd like to improve!
Binary: [url]https://dl.dropbox.com/u/51319671/gmsv_ezsock_win32.dll[/url]
Source: [url]https://dl.dropbox.com/u/51319671/gm_ezsock.zip[/url]
GLSock compatibility (connect, read and write support): [url]https://dl.dropbox.com/u/51319671/glsock_to_ezsock.lua[/url]
Useage
[lua]
-- HOST EXAMPLE
local hsock = EzSock(IPPROTO_TCP)
if (hsock:Bind(9999)) then
print("Socket bound to port 9999")
if (hsock:Listen()) then
print("Socket is now listend")
hook.Add("Think", "Socket_Accept", function()
local newsock = hsock:Accept()
if (newsock:IsValid()) then
print("Accepted new client!")
end
end)
end
end
-- CONNECT EXAMPLE
require("ezsock")
local sock = EzSock(IPPROTO_TCP) -- make the socket object
sock:Connect("google.com", 80)
local packet = EzPacket() -- create a packet object
packet:WriteString("GET /index.html HTTP/1.1\r\n", true) -- text, DontEndWith0Terminated
packet:WriteString("Host: www.google.com\r\n", true)
packet:WriteString("\r\n", true)
sock:Send(packet)
hook.Add("Think", "OneDoesNotSimplyMakeAsyncSocks", function()
local rpacket = sock:Read(1) -- try to recieve one byte
if (rpacket:IsValid()) then -- if it sucseeded in recieving data
Msg(string.char(rpacket:ReadByte()))
end
end)
[/lua]
Functions:
[code]
Socket:
EzSock() -- IPPROTO_TCP or IPPROTO_UDP, returns a new socket (UDP is not finished, so it wont work unless some black magic comes in)
sock:Connect(ip, port)
sock:Bind(port) -- binds to a port
sock:Listen() -- Listen
sock:Accept() -- accepts a socket, use IsValid() on the returned sock to see if it accepted one or not
sock:Close()
sock:IsError() -- if it returns true, you should create a new socket, srsly.
sock:CanRead() -- is there data to read?
sock:Send(packet) -- send a packet
sock:SendPacket(packet) -- this sends the packet, WITH a predefined int header, so you know the size of the packet on the reciving endpoint
sock:Read(len) -- attempts to recieve len bytes and returns a packet, check with IsValid() to see if it sucseeded
sock:TryRead(len) -- Try to read len bytes, check with packet:InSize > 0 if it worked / received something
sock:ReadPacket() -- this reads a packet WITH the predefined int header, so you wont need to fill in the length
sock:SetBlocking(bool) -- sets it to blocking or not, i asume you dont want your Gmod to freeze, so i would leave this at false, wich is the default
sock:IsValid() -- is this socket valid, as in, did we connect with it, did we host with it, or was this socket accepted by a hoster?
sock:GetIP() -- returns the ip of a connected socket
sock:GetPort() Le port
EzPacket() -- creates a packet object
packet:WriteByte(num)
packet:WriteShort(num)
packet:WriteInt(num)
packet:WriteLong(num)
packet:WriteFloat(num)
packet:WriteDouble(num)
packet:WriteString(str, bool) -- if you insert true, then it WONT write the 0 terminator
packet:ReadByte()
packet:ReadShort()
packet:ReadInt()
packet:ReadLong()
packet:ReadFloat()
packet:ReadDouble()
packet:ReadString(char) -- IF you supply char, it wil read until that, if you dont, it wil read unit the 0 terminator
packet:CanRead(len) -- Are there 500 bytes left to read?
packet:InSize() -- Get the length of a received packet
packet:HasDataLeft() -- is there somehing still to read?
packet:DataLeft() -- how much is there left?
packet:DataToSend() -- how much data is there ready to be send?
packet:IsValid() -- is this packet valid, as in, did it recieve something?
[/code]
fuck yeah
Optimized a few things, and fixed ReadLong, and crashing if the remote server rejects you and you try to read data.
And fixed a litle thing about the GLSock combatibility
[editline]7th October 2012[/editline]
Also, double and float support!
LINUX
[QUOTE=Python1320;37944694]LINUX[/QUOTE]
The thought makes me shudder
(I dont use linux myself, and never dev'd on it, I'll try to check if its not too hard for me to convert it)
Submitted to that cool module site that spencer made ([url]http://modules.gmodwiki.com[/url])
I'm probably stupid in saying this, but instead of checking to see if you have received data in a Think hook, couldn't you make a callback method for the sockets?
How do you think glsockets callbacks work? :v:
[QUOTE=BlackAwps;37954537]How do you think glsockets callbacks work? :v:[/QUOTE]
I have no clue.
[QUOTE=TGiFallen;37955375]I have no clue.[/QUOTE]
It makes an C++ thread, wich does handles all the networking, and once the think hook triggers on GMod, it checks if it has pending stuff that has to be executed in lua, if so, it does.
The only diffrence between my way and glsock's way is that im doing the think in lua, and glsock in c++
-snip
[QUOTE=I am God.;38031055][IMG]http://puu.sh/1eJJY[/IMG]
What else modules do I need?[/QUOTE]
afaik that doesn't mean you need a module you don't have, it means it failed to load that one.
I'd say you need the Visual Studio 2012 C++ Redistributables since the project is a Visual Studio 2012 one. [url]http://www.microsoft.com/en-us/download/details.aspx?id=30679[/url]
[QUOTE=danielga;38031959]I'd say you need the Visual Studio 2012 C++ Redistributables since the project is a Visual Studio 2012 one. [url]http://www.microsoft.com/en-us/download/details.aspx?id=30679[/url][/QUOTE]
Might be easier for everyone if you compiled it with vc10 (just get the express edition and change the compiler in vs2012) unless you're using a lot of the new c++11 features.
I compiled it with vc++ 10 if anyone doesn't have the required modules or can't install because of having XP (like me): [url]https://dl.dropbox.com/u/104036701/gmsv_ezsock.dll[/url] Source is same
Fixed sock:IsValid() at sockets returned by Accept()
Added sock:GetIP and sock:GetPort
And builded using vs10 toolset. Sorry for that!
Updated build with new header files!
The headers were updated the 2nd November. That's the cause I suppose.
EDIT: There's no significant changes though... Unless it's the changes garry made to userdata and how they work.
Can someone recompile with the userdata changes please :)
and a working udp would be great as well ! ;) there is non atm
Recompiled, and fixed float and double being send / received in the wrong endian!
No UDP and linux support tho. I'll do UDP next.
Still getting a userdata error with the updated binaries
[code]
[ERROR] lua/multiserv_sv.lua:22: calling 'Bind' on bad self ((null) expected, got userdata)
1. Bind - [C]:-1
2. InitListen - lua/multiserv_sv.lua:22
3. unknown - lua_run:1
[/code]
[lua]
multiserv.listensock = EzSock(IPPROTO_TCP)
if (multiserv.listensock:Bind(multiserv.port)) then
[/lua]
Mmmmmm, I'll have a look what Garry murdered in the checking to see if I can fix this.... Gah..
[editline]3rd November 2012[/editline]
Okay there, I have no idea how Garry wants me to do userdata currently, so i just removed all the checks, seems to work. Just try not to do something like this:
[lua]
-- BAAAAAD MMMKKAAAYY
local lolfunc = {Send = sock.Send}
lolfunc:Send(packet)
[/lua]
[code]#define EZSOCKTYPE 12469
#define EZPACKTYPE 12470[/code]
There's your problem. The type value is now an unsigned char, meaning between 0-255.
[QUOTE=BlackAwps;38304452][code]#define EZSOCKTYPE 12469
#define EZPACKTYPE 12470[/code]
There's your problem. The type value is now an unsigned char, meaning between 0-255.[/QUOTE]
Oh, derp. But, that means that we can only have up to 255 userdata types?
That's not much...
Besides, should it not overflow and 12470 turn out to be 182? (12470 % 256) or am I pampered by C# too much on that?
[QUOTE=bromvlieg;37940250]
[code]
packet:CanRead(len) -- Are there 500 bytes left to read?
packet:HasDataLeft() -- is there somehing still to read?
packet:DataLeft() -- how much is there left?
packet:DataToSend() -- how much data is there ready to be send?
[/code][/QUOTE]
sock:Read(len) - we need that len, we need to know how many bytes we can read. What's the point of knowing size of packet if we can't read that packet.
Or allow sock:Read function to read not only len bytes, but up to len.
Or add arg-less sock:Read function variant and allow it to read just all available bytes.
[QUOTE=vigi8;38325718]sock:Read(len) - we need that len, we need to know how many bytes we can read. What's the point of knowing size of packet if we can't read that packet.
Or allow sock:Read function to read not only len bytes, but up to len.
Or add arg-less sock:Read function variant and allow it to read just all available bytes.[/QUOTE]
I'm sorry, but I have no idea how do check incomming data, and google ain't telling me.
A way todo it, how I do it, is send 4 bytes with the packet size in it, so, first read 4 bytes, and then read the rest.
Another way to do it would do a while(true) and break the moment the packet returned by sock:Read(1) is not valid.
[QUOTE=bromvlieg;38330733]Another way to do it would do a while(true) and break the moment the packet returned by sock:Read(1) is not valid.[/QUOTE]
This won't work for UDP because it is an unreliable protocol. You either read a whole packet or you don't. After reading even a SMALL part of an UDP packet, it will be discarded right away.
Sorry, you need to Log In to post a reply to this thread.