[img]http://img256.imageshack.us/img256/953/oosocks.png[/img]
Please look [url]http://www.facepunch.com/threads/1136961[/url] for a more supported/stable library. Please consider this library deprecated.
OOSocks is multi-threaded, object orientated callback based module.
[release]
[highlight]Magic Definitions[/highlight]
Connection Type:
[lua]
IPPROTO_TCP
IPPROTO_UDP
[/lua]
Error Codes:
[lua]
SCKERR_OK
SCKERR_BAD
SCKERR_CONNECTION_RESET
SCKERR_NOT_CONNECTED
SCKERR_TIMED_OUT
[/lua]
Callback Types:
[lua]
SCKCALL_CONNECT
SCKCALL_LISTEN
SCKCALL_BIND
SCKCALL_ACCEPT
SCKCALL_REC_LINE
SCKCALL_REC_SIZE
SCKCALL_REC_DATAGRAM
SCKCALL_SEND
[/lua]
[/release]
[release]
[highlight]Functions[/highlight]
[lua]
-- Takes 1:
-- IPROTO_*
-- Returns 1:
-- OOSock Object
-- Callback none
OOSock( IPROTO_* )
-- Takes 2:
-- ip address - Note: An empty string as the ip will result in binding to every local ip.
-- port number
-- Returns 1:
-- call id number
-- Callback SCKCALL_BIND
OOSock:Bind( ip, port )
-- Takes 1:
-- connection backlog
-- Returns 1:
-- call id number
-- Callback SCKCALL_LISTEN
OOSock:Listen( backlog )
-- Takes 0:
--
-- Returns 1:
-- call id number
-- Callback SCKCALL_ACCEPT
OOSock:Accept( )
-- Takes 2:
-- hostname
-- port number
-- Returns 1:
-- call id number
-- Callback SCKCALL_CONNECT
OOSock:Connect( ip, port )
-- Takes 1(opt +2):
-- data string or BinWrite
-- [dest ip]
-- [dest port]
-- Returns 1:
-- call id number
-- Callback SCKCALL_SEND
OOSock:Send( data [, ip, port] )
-- Takes 1(opt +2):
-- data
-- [dest ip]
-- [dest port]
-- Returns 1:
-- call id number
-- Callback SCKCALL_SEND
OOSock:SendLine( data [, ip, port] )
-- Takes 1:
-- byte Count
-- Returns 1:
-- call id number
-- Callback SCKCALL_REC_SIZE
OOSock:Receive( byteCount )
-- Takes 0:
--
-- Returns 1:
-- call id number
-- Callback SCKCALL_REC_LINE
OOSock:ReceiveLine( )
-- Takes 0:
--
-- Returns 1:
-- call id number
-- Callback SCKCALL_REC_DATAGRAM
OOSock:ReceiveDatagram( )
-- Takes 1:
-- function(OOSocket, SCKCALL_*, SCKERR_*, dataString or OOSocket Object or false, peerIPString or false, peerPort )
-- Returns 0:
--
-- Callback none
OOSock:SetCallback( function )
-- Takes 1:
-- bool - false means the data parameter in the callback will always be a string.
-- - true means the data parameter in the callback will be a BinRead object.
-- Returns 0:
--
-- Callback none
OOSock:SetBinaryMode( bool )
-- Takes 0:
--
-- Returns 0:
--
-- Callback none
OOSock:Close( )
--------------------------------------------------------------------
-- Takes 0:
--
-- Returns 1:
-- Returns data size.
-- Callback none
BinRead:GetSize( )
-- Takes 0:
--
-- Returns 1:
-- Returns the position of the next item to be read.
-- Callback none
BinRead:GetReadPosition( )
-- Takes 0:
--
-- Returns 1:
-- Returns the Read Position to 0
-- Callback none
BinRead:Rewind( )
-- Takes 0:
--
-- Returns 1:
-- Reads 1byte, but does not change the Read Position
-- Callback none
BinRead:PeekByte( )
-- Takes 0:
--
-- Returns 1:
-- Reads 1bytes and returns it as a int.
-- Callback none
BinRead:ReadByte( )
-- Takes 0:
--
-- Returns 1:
-- Reads 8bytes and returns it as a double.
-- Callback none
BinRead:ReadDouble( )
-- Takes 0:
--
-- Returns 1:
-- Reads 4bytes and returns it as a int.
-- Callback none
BinRead:ReadInt( )
-- Takes 0:
--
-- Returns 1:
-- Reads 2bytes and returns it as a short.
-- Callback none
BinRead:ReadShort( )
-- Takes 0:
--
-- Returns 1:
-- Reads 4bytes and returns it as a float.
-- Callback none
BinRead:ReadFloat( )
-- Takes 0:
-- [opt Size] Optional size parameter, will read NULL terminated string if no size is provided.
-- Returns 1:
-- Reads a NULL terminated string. Read Position will be offset by string.len + 1 (the extra NULL char)
-- Callback none
BinRead:ReadString( [opt Size] )
--------------------------------------------------------------------
-- Takes 0:
--
-- Returns 1:
-- BinWrite Object
-- Callback none
BinWrite( )
-- Takes 1:
-- float
-- Returns 0:
--
-- Callback none
BinWrite:WriteFloat( float )
-- Takes 1:
-- double
-- Returns 0:
--
-- Callback none
BinWrite:WriteDouble( double )
-- Takes 1:
-- int
-- Returns 0:
--
-- Callback none
BinWrite:WriteInt( int )
-- Takes 1:
-- short
-- Returns 0:
--
-- Callback none
BinWrite:WriteShort( short )
-- Takes 1:
-- byte
-- Returns 0:
--
-- Callback none
BinWrite:WriteByte( byte )
-- Takes 1:
-- string
-- Returns 0:
--
-- Callback none
BinWrite:WriteString( string )
-- Takes 1:
-- string, this function will append a 0 byte to the end. Use BinRead:ReadString when reading a Zero Terminated String.
-- Returns 0:
--
-- Callback none
BinWrite:WriteStringZeroTerminated( string )
-- Takes 1:
-- BinWrite object to be appended to this BinWrite object.
-- Returns 0:
--
-- Callback none
BinWrite:WriteBinWrite( BinWrite )
-- Takes 0:
--
-- Returns 1:
-- size
-- Callback none
BinWrite:GetSize()
[/lua]
[/release]
[release]
[highlight]Basic HTTP connection example. I think it works ;)[/highlight]
[lua]
local connection = OOSock(IPPROTO_TCP);
connection:SetCallback(function(socket, callType, callId, err, data, peer, peerPort)
if(callType == SCKCALL_CONNECT and err == SCKERR_OK) then
print("Connected to google.com.au, YAY!");
socket:SendLine("GET /index.html HTTP/1.1");
socket:SendLine("Host: google.com.au");
socket:SendLine("");
socket:ReceiveLine();
end
if(callType == SCKCALL_REC_LINE and err == SCKERR_OK and data != "") then
print(data);
local lengthSig = "Content-Length: ";
if(string.Left(data, string.len(lengthSig)) == lengthSig) then
HTTPLen = tonumber(string.Right(data, string.len(data) - string.len(lengthSig)));
end
-- Get all the headers
socket:ReceiveLine();
elseif(callType == SCKCALL_REC_LINE and err == SCKERR_OK and data == "") then
socket:Receive(HTTPLen);
end
if(callType == SCKCALL_REC_SIZE) then
print(data);
end
end);
connection:Connect("google.com.au", 80);
[/lua]
[/release]
[release]
[highlight]Basic UDP Datagram send and receive.[/highlight]
[lua]
require("oosocks")
local connection = OOSock(IPPROTO_UDP);
connection:SetCallback(function(socket, callType, callId, err, data, peer, peerPort)
if(callType == SCKCALL_BIND && err == SCKERR_OK) then
print("Bound.");
connection:Send("rofl", "127.0.0.1", 37777);
connection:ReceiveDatagram();
end
if(callType == SCKCALL_SEND && err == SCKERR_OK) then
print("Sent.");
end
if(callType == SCKCALL_REC_DATAGRAM && err == SCKERR_OK) then
print("Got '" .. data .. "' from " .. peer .. ":" .. tostring(peerPort));
socket:Close()
end
if(err != SCKERR_OK) then
socket:Close()
end
end);
-- an IP of "" binds to all interfaces.
connection:Bind("", 37777);
[/lua]
[/release]
[release]
[highlight]Basic HTTP connection example. But this time using Binary Read[/highlight]
[lua]
require("oosocks");
local connection = OOSock(IPPROTO_TCP);
connection:SetBinaryMode(true);
connection:SetCallback(function(socket, callType, callId, err, binread, peer, peerPort)
if(callType == SCKCALL_CONNECT and err == SCKERR_OK) then
print("Connected to google.com.au, YAY!");
socket:SendLine("GET /index.html HTTP/1.1");
socket:SendLine("Host: google.com.au");
socket:SendLine("");
socket:ReceiveLine();
end
if(callType == SCKCALL_REC_LINE and err == SCKERR_OK and data != "") then
local size = binread:GetSize();
local data = "";
for i=1, size do
data = data .. string.char(binread:ReadByte());
end
print(data);
local lengthSig = "Content-Length: ";
if(string.Left(data, string.len(lengthSig)) == lengthSig) th
[QUOTE=haza55;21750683]
sock:Receive(4) // Read 4 bytes.
sock:ReceiveLine()
[/QUOTE]
If i use the sock:RevieveLine() wil my server freeze up until it gets something?
Also, could you please add an close function? it would be so much easyer to make things compatible whit the just died luasocket
The reason for it is, that ive writed an complete lua module format for it to controle the hole socket. (and i kinda need a replacement fast)
[QUOTE=bromvlieg;21751284]If i use the sock:RevieveLine() wil my server freeze up until it gets something?
Also, could you please add an close function? it would be so much easyer to make things compatible whit the just died luasocket[/QUOTE]
use SetTimeout to change how long the Receive functions wait for.
Setting to 0 means it will not wait for data.
It will return an empty string if data hasn't arrived yet.
I will also add a close function.
[QUOTE=haza55;21751306]use SetTimeout to change how long the Receive functions wait for.
Setting to 0 means it will not wait for data.
It will return an empty string if data hasn't arrived yet.
I will also add a close function.[/QUOTE]
So if i set the timeout to 0, then simply do that each tick, my server wont go die in a corner?
Yep.
[QUOTE=haza55;21751359]Yep.[/QUOTE]
:buddy:
Is there no way to make the waiting for a response threaded so it doesn't freeze GMod?
[QUOTE=maurits150;21751491]Is there no way to make the waiting for a response threaded so it doesn't freeze GMod?[/QUOTE]
[url=http://www.facepunch.com/showpost.php?p=21751340&postcount=4]Read[/url]
[QUOTE=bromvlieg;21751521][URL="http://www.facepunch.com/showpost.php?p=21751340&postcount=4"]Read[/URL][/QUOTE]
I still prefer waiting properly for my data instead of calling :Receive() each tick.
[QUOTE=bromvlieg;21751340]So if i set the timeout to 0, then simply do that each tick, my server wont go die in a corner?[/QUOTE]
incoming packets get queued until you read them. It still reads the package is still in the socket even after 5 minutes or so. So just read the socket every 5-60 seconds and you should be fine
Also please add a close function. Windows does not like it when you shutdown application before closing the socket
PS. I may be wrong here but this is how it worked for lua socket and my experience in c++ socket programming
[QUOTE=ColdFusion;21751824]packets will wait for your to read them. Put it in a timer and run it every 10 seconds or so. They will wait for the moment your read your socket. (at least this is how it worked for luasocktes)
Also please add a close function. Windows does not like it when you shutdown application before closing the socket[/QUOTE]
Simply deleting the OOSock object will close it. A close function would only be redundant.
Could you please make an asynchronous domain resolver so I could finally resolve domains without freezing the server?
Plus would be if it could do reverse resolves aka ip to domain.
Keep the suggestions coming, I need to get it working on linux first.
Allow binding to different ips.
[editline]03:30PM[/editline]
How do we know who sent what with UDP? GetPeerName I hope. Haven't tested yet.
Ive changed my lua file to your functions, now my server starts crashing once the server gets "activated" as in, player/bot joins
Trying to figure out what the error text says JUST before it shuts down... Time to get a 300FPS desctop recorder! (the message shows 0.0000000001 MS then crash)
Edit:
[IMG]http://img203.imageshack.us/img203/3870/26256039.png[/IMG]
I win :smug:
What functions are you using.
Excellent work, thank you, I was investigating LuaSocket and it was a disaster.
[QUOTE=haza55;21752975]What functions are you using.[/QUOTE]
-snip-
Edit:
Wait.. im debuging..
[QUOTE=bromvlieg;21752942]
[IMG]http://img203.imageshack.us/img203/3870/26256039.png[/IMG]
I win :smug:[/QUOTE]
What functions are you using?
And can you try it without the bots. Sine we are on a new engine etc.
Seems like the Connect is crashing me, Could we change to steam chat? maybe we can test a socket between us would be easyer so see whats cousing it, (steam: bromvliegbrombeer)
Edit:
AHA!
[lua]local ip, port = client:GetPeerName() // Thats the trobble maker![/lua]
[IMG]http://img402.imageshack.us/img402/1179/27937588.png[/IMG]
[img]http://stoned.bplaced.net/img/gmod2flockdraw.png[/img]
I like it so far :D
I added some error code stuff + better error protection.
GetLastError will return the error of the last function.
If you encounter an SCKERR_BAD, its best to create a new socket.
Nice! thay came in handy....
Now there still acting qutie weard the sockets of send and recieve
Sometimes it works perfect, and sometimes its VERRRRRY weardo, as example:
[IMG]http://img443.imageshack.us/img443/6758/98012683.png[/IMG]
And at this point, ive just made & listen & bind'ed the socket,
and the bottom one doesnt host, it only sends
Nice work... I was going to do something like this next, but you beat me to it :)
Ehm.. another weard thing...
Message: Test
Recieve(1024)
Output Test
Delay of about 5 seconds
Message: A
Recieve(1024)
Output Aest
ehmpzzz?
Seems if you read more then the current message, it wil regrab some of the old text
However, it doenst matter how much i send message A, whit Recieve(1024) it keeps recieving the Aest, or Best if i make it.
The new message overwrites the bytes of the old one, wich includes that if you read more then the current message, that it gets old data.
Any chance that we could get a function RecieveAll() as in, Recieve() but then just the text wich has been send, and not whit a given bytes
[QUOTE=bromvlieg;21759796]Ehm.. another weard thing...
Message: Test
Recieve(1024)
Output Test
Delay of about 5 seconds
Message: A
Recieve(1024)
Output Aest
ehmpzzz?
Seems if you read more then the current message, it wil regrab some of the old text
However, it doenst matter how much i send message A, whit Recieve(1024) it keeps recieving the Aest, or Best if i make it.
The new message overwrites the bytes of the old one, wich includes that if you read more then the current message, that it gets old data.
Any chance that we could get a function RecieveAll() as in, Recieve() but then just the text wich has been send, and not whit a given bytes[/QUOTE]
I'll have a look at that.
Also
[lua]
local client = server:Accept()
if (client == nil) then return end
if (client:GetLastError() != SCKERR_OK) then
print("Error while Accepting!")
return
end
local ip, port = client:GetPeerName()
[/lua]
The port is nil,
Seems like the GetPeerName returns IP, nil at start
Nice module, i will try it out later :downs:
<3 CMake
SetTimeout doesn't seem to work for Connect, my server freezes for about 20 seconds instead of 300 miliseconds.
Sorry, you need to Log In to post a reply to this thread.