Raised This Month: $ Target: $400
 0% 

Sockets Problem


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
aron9forever
Veteran Member
Join Date: Feb 2013
Location: Rromania
Old 06-16-2014 , 14:41   Sockets Problem
Reply With Quote #1

Have this code that retrieves some data from a php script once every 5 seconds, checks it and if it's new info then prints it.
The server running it , after a while, starts having freeze spikes, and after a while the server just dies. Doesn't crash, doesn't segmentate, just dies, it won't restart automatically and the process has to be terminated and run again.

I've used a tut I found on this forum for the socks, pretty much the only one available there, and copy pasted most of it, if someone knows how this mumbo jumbo works please see if something's wrong

Code:
#include <amxmodx> #include <sockets> #define PLUGIN_NAME "Radio BZ" #define PLUGIN_AUTHOR   "aron9forever" #define PLUGIN_VERSION  "1.1" #define REMOTE_HOST "piratefm.ro" #define SCRIPT_NAME "/comm/parser.php" new g_sckweb new g_esong[64] new g_rsong[64] new g_dsong[64] public plugin_init() {     register_plugin(PLUGIN_NAME, PLUGIN_VERSION, PLUGIN_AUTHOR)     set_task(5.0,"tests")     //set_task(40.0,"announce",_,_,_,"b",0) } public tests() {     set_task(5.0,"tests")     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: { chat_color(0, ".v[AMXX].e Error creating socket"); }             case 2: { chat_color(0, ".v[AMXX].e Error resolving remote hostname"); }             case 3: { chat_color(0, ".v[AMXX].e 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"))             {                 if(!equal(line_value, g_rsong))                 {                     set_hudmessage(0, 255, 0, 0.02, -1.0);                     show_hudmessage(0, "PirateFM Rap canta: -%s-", line_value);                     chat_color(0, ".v[AMXX].ePirateFM Rap canta: -%s-", line_value)                     g_rsong = line_value                 }             }             if (equal(line_variable, "some_value2"))             {                 if(!equal(line_value, g_esong))                 {                     set_hudmessage(0, 255, 0, 0.02, -1.0);                     show_hudmessage(0, "PirateFM Electro canta: -%s-", line_value);                     chat_color(0, ".v[AMXX].ePirateFM Electro canta: -%s-", line_value)                     g_esong = line_value                 }             }             if (equal(line_variable, "some_value3"))             {                 if(!equal(line_value, g_dsong))                 {                     set_hudmessage(0, 255, 0, 0.02, -1.0);                     show_hudmessage(0, "PirateFM Dub canta: -%s-", line_value);                     chat_color(0, ".v[AMXX].ePirateFM Dub canta: -%s-", line_value)                     g_dsong = line_value                 }             }         }       }     if (g_sckweb != 0)     set_task(0.5, "read_web")     else     disconnect_web()     return PLUGIN_HANDLED } public write_web(text[512]) {     socket_send(g_sckweb, text, 511) } public disconnect_web() {     chat_color(0, ".v[AMXX].e Socket disconnected")     socket_close(g_sckweb) } 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 } stock chat_color(const id, const input[], any:...) {     new count = 1, players[32]     static msg[191]     vformat(msg, 190, input, 3)     replace_all(msg, 190, ".v", "^4")     replace_all(msg, 190, ".g", "^1")     replace_all(msg, 190, ".e", "^3")     if (id) players[0] = id; else get_players(players, count, "ch")     {         for (new i = 1; i < count; i++)         {             if (is_user_connected(players[i]))             {                 message_begin(MSG_ONE_UNRELIABLE, get_user_msgid("SayText"), _, players[i])                 write_byte(players[i]);                 write_string(msg);                 message_end();             }         }     } }
__________________
Meanwhile, in 2050:
Quote:
Originally Posted by aron9forever
useless small optimizations
Quote:
Originally Posted by Black Rose View Post
On a map that is 512x512x128 units you end up with 3,355,443,200,000 different "positions". To store each one of those positions individually in the variable "user_or" you need 12 terabytes of memory.
aron9forever is offline
Old 06-17-2014, 08:07
aron9forever
This message has been deleted by YamiKaitou. Reason: wait 14 days before you bump
Black Rose
Veteran Member
Join Date: Feb 2011
Location: Stockholm, Sweden
Old 06-20-2014 , 21:01   Re: Sockets Problem
Reply With Quote #2

You don't read the whole result. If you add simple debug messages like this:
Code:
        socket_recv(g_sckweb, buf, 511)         server_print("Response len: %d^n^nResponse:^n%s^n", strlen(buf), buf)
Then you will notice you do get a response, just not enough of it.
Code:
Response len: 400

Response:
HTTP/1.1 200 OK
Date: Sat, 21 Jun 2014 00:56:43 GMT
Server: Apache/2.2.25 (Unix) mod_ssl/2.2.25 OpenSSL/0.9.8e-fips-rhel5 mod_bwlimited/1.4 mod_qos/10.10 mod_fcgid/2.3.6
X-Powered-By: PHP/5.3.27
Vary: Accept-Encoding,Use
What you have to do is find out the length of the page by parsing the HTTP header for this:
Code:
Content-Length: 173
Break off the header and then receive until you reach that amount of bytes. The header size is not included in Content-Length.
Then you will be left with the contents of the page.

What is good to know here is that you do not decide the length of the reply. Even if you supply a string that is big enough, it might get cut off for no apparent reason. I don't know why.

I don't see a reason for it to crash though.
__________________

Last edited by Black Rose; 06-20-2014 at 21:16.
Black Rose is offline
aron9forever
Veteran Member
Join Date: Feb 2013
Location: Rromania
Old 06-20-2014 , 22:15   Re: Sockets Problem
Reply With Quote #3

Quote:
Originally Posted by Black Rose View Post
You don't read the whole result. If you add simple debug messages like this:
Code:
        socket_recv(g_sckweb, buf, 511)         server_print("Response len: %d^n^nResponse:^n%s^n", strlen(buf), buf)
Then you will notice you do get a response, just not enough of it.
Code:
Response len: 400

Response:
HTTP/1.1 200 OK
Date: Sat, 21 Jun 2014 00:56:43 GMT
Server: Apache/2.2.25 (Unix) mod_ssl/2.2.25 OpenSSL/0.9.8e-fips-rhel5 mod_bwlimited/1.4 mod_qos/10.10 mod_fcgid/2.3.6
X-Powered-By: PHP/5.3.27
Vary: Accept-Encoding,Use
What you have to do is find out the length of the page by parsing the HTTP header for this:
Code:
Content-Length: 173
Break off the header and then receive until you reach that amount of bytes. The header size is not included in Content-Length.
Then you will be left with the contents of the page.

What is good to know here is that you do not decide the length of the reply. Even if you supply a string that is big enough, it might get cut off for no apparent reason. I don't know why.

I don't see a reason for it to crash though.

I don't have any problems with incomplete reads or stuff like that. The only things are the server crashes, which I've been reported from multiple servers using the plugin running multiple mods, so I'm sure this is causing it.
This is the full script without anything edited.



I really need to fix this. As I said, server starts lagging once every couple of minutes (hard lag, like a huge denial of service, but I doubt it's the bandwidth, the other servers on the same machine run fine), then just crashes completely(process stops, can't auto restart) without giving any errors or any weird stuff in the console. It's like someone just kills it
__________________
Meanwhile, in 2050:
Quote:
Originally Posted by aron9forever
useless small optimizations
Quote:
Originally Posted by Black Rose View Post
On a map that is 512x512x128 units you end up with 3,355,443,200,000 different "positions". To store each one of those positions individually in the variable "user_or" you need 12 terabytes of memory.

Last edited by aron9forever; 09-10-2014 at 14:52.
aron9forever is offline
Black Rose
Veteran Member
Join Date: Feb 2011
Location: Stockholm, Sweden
Old 06-20-2014 , 23:52   Re: Sockets Problem
Reply With Quote #4

I guess this is just how remote connections work sometimes. 5s refresh is kind of spamming.
Consider using SQL instead to cache the information if possible.
__________________
Black Rose is offline
aron9forever
Veteran Member
Join Date: Feb 2013
Location: Rromania
Old 06-21-2014 , 07:07   Re: Sockets Problem
Reply With Quote #5

Quote:
Originally Posted by Black Rose View Post
I guess this is just how remote connections work sometimes. 5s refresh is kind of spamming.
Consider using SQL instead to cache the information if possible.
so make the php file store the data in a db and then retrieve it from the plugin?
there are a couple of problems with this: I don't know how to set up a cron job or whatever's needed to make it work on it's own, and I didn't understand crap from what's written about it
As some may notice I'm total shit in php
and finally, access to a db that allows remote connections. I'll just move the php to the same machine


Do you think lowering it to 10 seconds could help?
What about changing from SOCKET_TCP to SOCKET_UDP? I've read that it's basically the MSG_ONE_UNRELIABLE of communication, and much less bandwidth consuming

If you don't know I'll try it anyways but maybe someone knows this stuff
__________________
Meanwhile, in 2050:
Quote:
Originally Posted by aron9forever
useless small optimizations
Quote:
Originally Posted by Black Rose View Post
On a map that is 512x512x128 units you end up with 3,355,443,200,000 different "positions". To store each one of those positions individually in the variable "user_or" you need 12 terabytes of memory.
aron9forever is offline
Black Rose
Veteran Member
Join Date: Feb 2011
Location: Stockholm, Sweden
Old 06-21-2014 , 10:47   Re: Sockets Problem
Reply With Quote #6

The thing is this. The domain is yours, so whatever software is running it is feeding it with information somehow. That's where you add the SQL, if not already there.

I think UDP is generally hard to work with. I have limited experience though. I couldn't get socket_change() to work at all. (Maybe it's not supposed to?) which meant I had to hardcode the timing and just hope I would get an answer.
__________________

Last edited by Black Rose; 06-21-2014 at 10:47.
Black Rose is offline
aron9forever
Veteran Member
Join Date: Feb 2013
Location: Rromania
Old 06-21-2014 , 11:48   Re: Sockets Problem
Reply With Quote #7

Quote:
Originally Posted by Black Rose View Post
The thing is this. The domain is yours, so whatever software is running it is feeding it with information somehow. That's where you add the SQL, if not already there.

I think UDP is generally hard to work with. I have limited experience though. I couldn't get socket_change() to work at all. (Maybe it's not supposed to?) which meant I had to hardcode the timing and just hope I would get an answer.
I can't. The software is a radio host called "Shoutcast" and is closed source and discontinued at the moment, and doesn't have such features.
I have the plain text site tho, where the info is.
__________________
Meanwhile, in 2050:
Quote:
Originally Posted by aron9forever
useless small optimizations
Quote:
Originally Posted by Black Rose View Post
On a map that is 512x512x128 units you end up with 3,355,443,200,000 different "positions". To store each one of those positions individually in the variable "user_or" you need 12 terabytes of memory.
aron9forever is offline
aron9forever
Veteran Member
Join Date: Feb 2013
Location: Rromania
Old 07-04-2014 , 09:11   Re: Sockets Problem
Reply With Quote #8

this still isn't fixed
__________________
Meanwhile, in 2050:
Quote:
Originally Posted by aron9forever
useless small optimizations
Quote:
Originally Posted by Black Rose View Post
On a map that is 512x512x128 units you end up with 3,355,443,200,000 different "positions". To store each one of those positions individually in the variable "user_or" you need 12 terabytes of memory.
aron9forever is offline
vlad_slick
Member
Join Date: Jul 2009
Old 07-04-2014 , 16:31   Re: Sockets Problem
Reply With Quote #9

Here are some tips:
- I added a server_print each time a function is called in your plugin, and the read_web function gets executed more and more often as time goes by (10 min after starting the server, it's called 2580 times each 5 seconds), until, at some point, the server can't handle it and hangs

- the chat_color function you used is incorrect (it has extra brackets and skips a player), use ColorChat v0.3.2 by ConnorMcLeod;

- if you want to handle the sockets, have a look at how xREDIRECT by xOR handles socket communication (error handling, socket reading, etc.); it's made for UDP sockets, but you can get ideas from it;

- another sockets option would be to use Bugsy's [INC] HTTP, which handles the socket communications, and just downloads a file, which you could read with amx

-if you don't want to use sockets you could try the Threaded HTTP module by joropito, it's much easier to use ( but I haven't been able to make it work on Windows)

Last edited by vlad_slick; 07-04-2014 at 16:37. Reason: added another option
vlad_slick is offline
aron9forever
Veteran Member
Join Date: Feb 2013
Location: Rromania
Old 07-05-2014 , 06:47   Re: Sockets Problem
Reply With Quote #10

Quote:
Originally Posted by vlad_slick View Post
Here are some tips:
- I added a server_print each time a function is called in your plugin, and the read_web function gets executed more and more often as time goes by (10 min after starting the server, it's called 2580 times each 5 seconds), until, at some point, the server can't handle it and hangs
Are you sure about this?
I have no idea why it would do that, there's no looping task other than
PHP Code:
public tests()
{
    
set_task(5.0,"tests")
    
connect_web()

I honestly can't see how that might happen, 500 times a second means some shit is seriously wrong





The chat color is running fine and doesn't skip players (get_players returns 33 on full server)


Anyone here see just how this infinite looping could happen? I've asked the opinion of many other experienced scripters and nobody noticed anything wrong in the code.
Also, I used the only sockets tutorial available online, came from here...



edit::

tested some stuff

1)deleting set_task(5.0,"tests") from "public tests()" results in the song changes not showing, they are only shown once when the task is first called

2)deleting "if (g_sckweb != 0)
set_task(0.5, "read_web")
else" from the end of read_web() results in the plugin not showing anything, ever

3) deleting " if (g_sckweb != 0)

else
disconnect_web()" and leaving set_task(0.5, "read_web") while also deleting set_task(5.0,"tests") from "public tests()" results in the plugin not showing anything


I'm really lost in the way these sockets work.

The only explanation for you getting 500 tasks per second is that every time tests is ran, another 2 read_webs are being called per second from set_task(0.5, "read_web")

For 10 minutes, 600 seconds, that would be 1200 tasks per second and not 500, but still, if I remove that nothing works
any other suggestions? I'd like to leave this system in place and not rewrite everything with something else, it's as basic as it can get
__________________
Meanwhile, in 2050:
Quote:
Originally Posted by aron9forever
useless small optimizations
Quote:
Originally Posted by Black Rose View Post
On a map that is 512x512x128 units you end up with 3,355,443,200,000 different "positions". To store each one of those positions individually in the variable "user_or" you need 12 terabytes of memory.

Last edited by aron9forever; 07-05-2014 at 07:16.
aron9forever is offline
Reply



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 01:22.


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