Raised This Month: $238 Target: $400
 59% 

Sockets and webservers


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
DarkSnow
Senior Member
Join Date: Oct 2005
Location: 127.0.0.1
Old 07-23-2006 , 13:19   Sockets and webservers
Reply With Quote #1

I havent seen any good tutor on sockets and amx mod x so i decided to write some information on sockets, how to use them, why to use them and a small example im pawn on how to retrive webpage data from a webserver.


Before we begin
As pointed out futher down the threads, if you intend to connect to webservers to display parsed html - use the show_motd command right away - dont use sockets for this!

Code:
show_motd(id, "http://www.mywebsite.com/", "Window title")

About sockets
A socket is a term that describes the process of a communication between two computers. You have to specify when you create a socket - a destination adress, a destination port number and a protocol in which the socket will transfer data.

The destination adress could be an IP adress, or a domain. (xxx.xxx.xxx.xxx or xxxxx.xxx)

The port number depends on the server application, but the most commonly used ports are:
#21 - FTP
#23 - Telnet
#25 - SMTP
#80 - HTTP


Sockets and AMXX
In AMX Mod X you cannot use sockets to create your own server, so basicly you can only "call others", other computers cannot "call to you".

For example, you can connect in AMXX to a IRC server as a client, and send/recive messages - but you cant through an IRC client connect to your AMXX plugin.


More on protocols
When you are making a plugin using sockets, you have to code the protocol of the individual server type you aim to connect to.

If you imagine that you have an IRC client, and you try to connect to www.google.se - well, lets just say that it's neither very smart or atleast you wont access that website. Why? The IRC client has a built in "protocol", in which it expects a certain values and responses.

Since the IRC protocol differs from the web protocol, the two application can not communicate with each others. It is however possible to combine several protocols to be able to listen to both types of servers, but thats another story.

Here follows some specifications on certain protocols you might find usefull:
FTP: http://cr.yp.to/ftp.html
SMTP: http://www.ietf.org/rfc/rfc0821.txt
Telnet: http://www.scit.wlv.ac.uk/~jphb/comms/telnet.html
HTTP: http://www.jmarshall.com/easy/http/
MSN Messenger: http://www.hypothetic.org/docs/msn/n...le_session.php

Why use sockets?
As mentioned before, sockets can be used for basicly anything that requires communication between two or more computers.

Some examples of usage would be:
* Automatic checking of new versions
* Email authentication
* IRC bots

Hell, its even in theory possible to create a socket bot for counter-strike with alot of work


Sample application
The following example will connect to a website, request a page and return a value from that page.

Code:
#include <sockets> new g_sckweb //socket "id" #define SCRIPT_NAME "/myplugin/parser.php" #define REMOTE_HOST "myserver.com" //port d.80 public plugin_init() {     register_plugin("Socket sample", "??" ,"Darksnow")     set_task(5.0,"connect_web") } public connect_web() {     new error = 0     new constring[512]     g_sckweb = socket_open(REMOTE_HOST, 80, SOCKET_TCP, error)     if (g_sckweb > 0)     {         format(constring,511,"GET %s HTTP/1.1^nHost: %s^n^n",SCRIPT_NAME,REMOTE_HOST)         write_web(constring)         read_web()     }     else     {     switch (error)     {         case 1: { server_print("Error creating socket"); }         case 2: { server_print("Error resolving remote hostname"); }         case 3: { server_print("Error connecting socket"); }     }     return PLUGIN_CONTINUE } public read_web() {     const SIZE = 63     new line_variable[SIZE + 1], line_value[SIZE + 1]     if (socket_change(g_sckweb, 100))     {     new buf[512], lines[30][100], count = 0     socket_recv(g_sckweb, buf, 511)     count = ExplodeString(lines, 50, 119, buf, 13)     for(new i=0;i<count;i++)     {         parse(lines[i], line_variable, SIZE, line_value, SIZE)         if (equal(line_variable, "some_value"))         {             server_print("Value is %s", line_value)         }     }        if (g_sckweb != 0)         set_task(0.5, "read_web")     else         disconnect_web() } public write_web(text[512]) {     socket_send(g_sckweb, text, 511) } public disconnect_web() {     server_print("Socket disconnected") } stock ExplodeString( p_szOutput[][], p_nMax, p_nSize, p_szInput[], p_szDelimiter ) { // Function by xeroblood     new nIdx = 0, l = strlen(p_szInput)     new nLen = (1 + copyc( p_szOutput[nIdx], p_nSize, p_szInput, p_szDelimiter ))     while( (nLen < l) && (++nIdx < p_nMax) )         nLen += (1 + copyc( p_szOutput[nIdx], p_nSize, p_szInput[nLen], p_szDelimiter ))     return nIdx }

You will also need a web page. The following page is in php (but any webpage could do):
Code:
<?php
Header("Content-Type: text/plain");
if ($_GET['request'] == "version") //request current version?
	echo chr(13)."\"current_version\" \"1.0.4b\"";
else
	echo chr(13)."\"some_value\" \"this is the returned value\"";
?>
Yea i know, its alot of stuff for a simple task, which brings us to the final thoughts...


Larger protocols
Interacting with webservers is protocol-wise a piece of cake. You just have to submit a formated header to the server, describing what page you are looking for and perhaps some metadata (form/query)

But most protocols out there are pretty funky, so I think it couldnt hurt to demonstrate a more complex protocol.

Here follows an example on how user authentication might look like:
Code:
S=Server
C=Client

>>Connect <someserver> <someport>
C AUTH some_user wrong_password
S ERR 04 //wrong password
>>Server closes connection
>>Reconnect <someserver> <someport>
C AUTH some_user right_password
S welcome_message|server:xxx.xxx.xxx.xxx:xxxx|v0.25
>>Server closes connection
Basicly what we are looking as is how the client and server are talking to each other.

The client tries to connect, and authenticates with a wrong password - so the server terminates the connection with an error code. So, you as the developer have to codewise enterperate the error code and explain to the user that his/her's password didnt match.

Next, we try again and succeed. The server replies a welcome message for the user, and returns a new ip, port and server version.

Now you codewise have to first of all, check if your application can communicate with the server with that protocol version - secondly you have to reconnect to that given server and possibly re-authenticate.

The list of client/server "talk" can grow as long as my arm, but i want to keep this as simple as possible. This is just to show the basics of how protocols work, and hopfully it might be easier to read more complex real-life protocols.

Take a moment and compare the above example with the protocol of MSN Messenger, and hopfully it will make more sense now even for those lesser experienced: http://www.hypothetic.org/docs/msn/n...le_session.php


Should I use sockets in my plugins?
The most obious reply would prolly be: Do you really need sockets?

Some people find sockets distruptive, some hl-server hosting companies does not allow them - so it basicly comes down to the developers own good judgement.

Another drawback is that the end-user must enable the sockets module in order for this to work, and end-users can be pesky about it in general.

People around here will slash your guts open if you do something as stupid as combining an intro-music plugin combined with a irc bot, however if you need for your plugin to store-retrive values through a shared sql server - and dont want the sql password to be common knowlege, socket connection combined with php could be a good alternative.

So... Think and re-think, make some sketches and stuff before you decide to make any socket-client stuff in your plugins.


TCP vs UDP
The above example uses a TCP type of connection. In pawn, you can also use UDP as package transfer protocol. Confused? I will take it from the start

The TCP protocol is the most used protocol on the internet. Most "traditional" servers use it, such as webservers, smtp servers... Even MSN Messenger, IRC and Telnet use TCP.

The UDP protocol are more commonly used by gaming servers and p2p binary transfers.

So, we now have a clue on what uses what. So what is the big difference anyway? And why?

TCP "packages" consists of two parts. The header, which you rarely have to deal with, and the body (with its own sub-headers). The header of the TCP packages can sometimes be large, and contains a ton of CRC data, and general consistensity data - to ensure that no packages will be either lost or damaged.

Also, TCP always knows exactly when a client is online or dropps from an keep-alive connection.

To compare, UDP is more lightweight - has less headers and no CRC checksums etc. UDP does not realy give a crap if the reciver actualy recives the data, or if the data is intact - or even if there really is any reciver to begin with.

So basicly, the pro's and cons:
* TCP is slow, but very reliable. No lost or damaged packages (mostly)
* UDP is fast and flexible, consumes less bandwidth - but is unreliable, and not recomended for sensetive data.

I hope this has given some clarity of what TCP and UDP is.


Footer
I hope this reading has been enjoyable by both beginners aswell as intermediate developers here on the community.

Sorry it got so long, but its a huge topic.

For the functions of the socket module for AMX Mod X: http://www.amxmodx.org/doc/index.htm...ts%2Findex.htm

This document were written by: Darksnow
__________________

Last edited by DarkSnow; 03-07-2008 at 08:19. Reason: Added section on UDP-TCP/IP and protocol example
DarkSnow is offline
Send a message via MSN to DarkSnow
Zenith77
Veteran Member
Join Date: Aug 2005
Old 07-24-2006 , 14:36   Re: Sockets and webservers
Reply With Quote #2

First thing, you couldn't have wrote this tutorial at a better time for me!

Second, what exactly is the explode string doing?
__________________
Quote:
Originally Posted by phorelyph View Post
your retatred
Zenith77 is offline
DarkSnow
Senior Member
Join Date: Oct 2005
Location: 127.0.0.1
Old 07-24-2006 , 14:44   Re: Sockets and webservers
Reply With Quote #3

Quote:
Originally Posted by Zenith77
First thing, you couldn't have wrote this tutorial at a better time for me!

Second, what exactly is the explode string doing?
Glad you like it

The explode string breaks down the input returned from the server from a single string into a variable, exploded (seperated) by the original strings return characters (ascii-13)
__________________
DarkSnow is offline
Send a message via MSN to DarkSnow
Zenith77
Veteran Member
Join Date: Aug 2005
Old 07-24-2006 , 14:58   Re: Sockets and webservers
Reply With Quote #4

Ok so, this string

(C style return chars)
Code:
"NAME: w00t\r VALUE: Hello World"

would be ("exploded")

Code:
new var[2][50] var[0] = "NAME: w00t"; var[1] = "VALUE: Hello World";
__________________
Quote:
Originally Posted by phorelyph View Post
your retatred
Zenith77 is offline
Greenberet
AMX Mod X Beta Tester
Join Date: Apr 2004
Location: Vienna
Old 07-24-2006 , 15:04   Re: Sockets and webservers
Reply With Quote #5

only if delimiter is '\r'
Greenberet is offline
Send a message via ICQ to Greenberet Send a message via MSN to Greenberet
DarkSnow
Senior Member
Join Date: Oct 2005
Location: 127.0.0.1
Old 07-24-2006 , 22:15   Re: Sockets and webservers
Reply With Quote #6

Quote:
Originally Posted by Zenith77
Ok so, this string

(C style return chars)
Code:
"NAME: w00t\r VALUE: Hello World"

would be ("exploded")

Code:
new var[2][50] var[0] = "NAME: w00t"; var[1] = "VALUE: Hello World";

Yes, basicly it breaks down:
Code:
line #1
line #2
line #3
to
Code:
new lines[3][100]
lines[0] == "line #1"
lines[1] == "line #2"
lines[2] == "line #3"
etc... The function returns number of "new" variables inserted to the array.

It basicly works like php's "explode" function: http://is2.php.net/explode
__________________
DarkSnow is offline
Send a message via MSN to DarkSnow
Freecode
Never Fall Asleep
Join Date: Jan 2004
Old 07-24-2006 , 22:18   Re: Sockets and webservers
Reply With Quote #7

a better example of explode is
new string = "hi||i||am||gaben";
new stuff = explode("||",string);

and itl look like this
stuff[0] = "hi"
stuff[1] = "i"
stuff[2] = "am"
stuff[3] = "gaben"
Freecode is offline
Nostrodamous
BANNED
Join Date: Oct 2006
Old 11-02-2006 , 07:52   Re: Sockets and webservers
Reply With Quote #8

Nice tutorial , theres a super amount of very usefull information here. nice work ! ++Karma(karma being incremented)
Nostrodamous is offline
DarkSnow
Senior Member
Join Date: Oct 2005
Location: 127.0.0.1
Old 11-18-2006 , 21:08   Re: Sockets and webservers
Reply With Quote #9

Quote:
Originally Posted by Nostrodamous View Post
Nice tutorial , theres a super amount of very usefull information here. nice work ! ++Karma(karma being incremented)
Thanks, im glad you found it usefull
__________________
DarkSnow is offline
Send a message via MSN to DarkSnow
DotNetJunkie
Senior Member
Join Date: May 2005
Location: In front of my pc
Old 11-19-2006 , 17:49   Re: Sockets and webservers
Reply With Quote #10

Quote:
Originally Posted by DarkSnow
In AMX Mod X you cannot use sockets to create your own server, so basicly you can only "call others", other computers cannot "call to you".
I have a modified version of the sockets module I wrote, for AMXX version I forget, that will allow you to listen for connections.

In fact I wrote a simple web server in PAWN but unfortunately its getting
really complicated because I need to parse cookies and other stuff like
that to do anything more advanced.
__________________
DotNetJunkie is offline
Send a message via ICQ to DotNetJunkie Send a message via AIM to DotNetJunkie Send a message via MSN to DotNetJunkie Send a message via Yahoo to DotNetJunkie
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 23:51.


Powered by vBulletin®
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Theme made by Freecode