Author Topic: TCP Object Tutorial  (Read 2544 times)

Can anyone give me a tutorial on TCP objects, because I've never really used them and they seem interesting.

I will if no one else gets to it in a while, but I must say that they are the stuff.

I will if no one else gets to it in a while, but I must say that they are the stuff.
Wait, are the tutorials stuff or are the TCP objects stuff?

It depends what you're doing. If you're downloading files then it's necessary to use TCP, if you're using a custom protocol more than likely you'll need to use TCP, but if you're just connecting to a website then your best choice is an HTTP object. Granted, HTTP objects can only send GET requests, but most likely if you'll be sending a POST request you'll have to deal with a bunch of complicated things like cookies and PHP sessions that would go way outside the range of any tutorial for TorqueScript.

To connect to a website with HTTP it's pretty easy.
Code: [Select]
new httpObject(HTTPTest);
function HTTPTest::onLine(%this, %line)
{
    echo(%line);
}
HTTPTest.get("blockland.us","index.html");
This will echo every line of HTML the server sends back. You'll need to write your own custom parsing algorithm, I made an HTML parser but it's at home so I won't have it for a while.

Using TCP objects is a good bit more complicated. This is the TCP equivalent for the same thing:
Code: [Select]
new TCPObject(TCPTest);
function TCPTest::onLine(%this, %line)
{
    echo(%line);
}
function TCPTest::onConnected(%this)
{
    %this.send("GET /index.html HTTP/1.0\r\nHost: blockland.us\r\n\r\n");
}
TCPTest.connect("blockland.us:80");
Those requests can get really complicated really fast. For example, if you wanted to send a request to the a server with a payload of a name and IP, you'd have to send a request like this:
%payload = "name=" @ %name @ "&ip=" @ %ip;
%request = "POST /something.php HTTP/1.0\r\nHost: someHost.com\r\nContent-Length=" @ strLen(%payload) @ "\r\n\r\n" @ %payload @ "\r\n";

So anyway, as I said the requests can get really complicated and go way outside the scope of any tutorial any one of us will type. You'll have to research HTTP requests yourself, my only tip is to always use HTTP/1.0 not HTTP/1.1 because 1.1 can send a bunch of way more complicated data that is much more difficult to parse.

Here's a couple of default functions you can overwrite for your needs:
TCPObject::onConnected( %this )
TCPObject::onConnectFailed( %this )
TCPObject::onDisconnected( %this )
TCPObject::onLine( %this, %line )

So that's for visiting webpages. Then there's code for downloading pages. This one actually isn't too much more complicated, but there's a few more steps.

Code: [Select]
new TCPObject(downloadTCP) { outputFile = "config/image.png"; }
function downloadTCP::onLine(%this, %line)
{
    if(%line $= "") //end of headers
        %this.setBinary(1);
}
function downloadTCP::onBinChunk(%this, %size)
{
    cancel(%this.save);
    %this.save = %this.schedule(1000, saveBufferToFile, %this.file);
}
downloadTCP.connect("blockland.us:80");
downloadTCP.send("GET /frontpage/frontpage-shaders-00.jpg HTTP/1.0\r\nHost: blockland.us\r\n");
I find this particular way of doing it a good bit easier than the "more correct" way of parsing the headers, setting the binary size, checking when the size goes over that threshold, and saving, but this way works 99.9% of the time and doesn't require parsing the headers.

Anyway, I'm sure you'll have a lot of questions, so go ahead and ask.
« Last Edit: January 13, 2013, 02:29:03 PM by !Trinick »

Wait, are the tutorials stuff or are the TCP objects stuff?

He's saying TCP objects are the stuff, implying he likes them.

._.

Copy-pasting the first function into the console just says this:



I tried assigining the tcpObject to a global variable and it worked, but all it printed was "index.html":



I have no idea what i'm doing ;-;

Oops. I instantiated it as a TCPobject instead of an HTTPObject. Fixed.

Also, it was because you were calling ::onLine with the connection data. You need to use ::get for that. Also, use . instead of ::. I have a feeling you don;t know a ton about coding (mainly because of that) so maybe you should learn more before trying to tackle TCP objects, they're pretty complicated.
« Last Edit: January 13, 2013, 02:31:59 PM by !Trinick »

Can a TCP object download a binary file from somewhere?

Can a TCP object download a binary file from somewhere?
Correct.

Yes.

This will download a file.

Code: [Select]
$server = "greekmods.webs.com";
$port = 80;
$dir = "/mods/Gamemode_Slayer/Updater/changeLog_Latest.txt";
$saveTo = "config/server/TCP example.txt";

new TCPObject(tcp);

function tcp::onConnected(%this)
{
%this.send("GET" SPC $dir SPC "HTTP/1.0\nHost:" SPC $server @ "\r\n\r\n");
}

function tcp::onLine(%this,%line)
{
warn("LINE:" SPC %line);

//ONLY NEEDED IF SAVING THE BINARY FILE
if(strPos(%line,"Content-Length:") >= 0)
%this.length = getWord(%line,1);

//ONLY NEEDED IF SAVING THE BINARY FILE
if(%line $= "")
%this.setBinarySize(%this.length);
}

//ONLY NEEDED IF SAVING THE BINARY FILE
function tcp::onBinChunk(%this,%chunk)
{
if(%chunk < %this.length)
return;

%this.saveBufferToFile($saveTo);
%this.disconnect();
}

tcp.connect($server @ ":" @ $port);

That is set to download a file from my website. Simply change $server and $dir (and pick less generic names for everything).
« Last Edit: January 13, 2013, 06:37:23 PM by Greek2me »


All I want to do is make a chat-server thing like RTB. :(

All I want to do is make a chat-server thing like RTB. :(

That isn't easy, well it depends. Learn TCP/HTTP objects first and get used to them, then work it out.

All I want to do is make a chat-server thing like RTB. :(
Oh lol
You need a Server for that, which you'd either have to write externally or use a nonstop Blockland to do.