• OOSocks
    279 replies, posted
[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.