Register forum user name Search FAQ

Gammon Forum

Notice: Any messages purporting to come from this site telling you that your password has expired, or that you need to verify your details, confirm your email, resolve issues, making threats, or asking for money, are spam. We do not email users with any such messages. If you have lost your password you can obtain a new one by using the password reset link.

Due to spam on this forum, all posts now need moderator approval.

 Entire forum ➜ SMAUG ➜ SMAUG coding ➜ Using Descriptors Without an Open Socket Connection?

Using Descriptors Without an Open Socket Connection?

It is now over 60 days since the last post. This thread is closed.     Refresh page


Posted by Kris   USA  (198 posts)  Bio
Date Wed 29 Oct 2003 05:10 PM (UTC)
Message
Heya. I'm currently in the process of writing a totally web-based client in PHP for my MUD. Such a thing is good in situations where even java telnet isn't an option, such as if you're behind a tight firewall (like I am at work hehe). Maintaining a constant open connection in PHP is simply not possible due to the way it's setup, as I'm sure you already know (took me awhile to figure that out for myself though).

So here's the premise: Make the initial connection on a special port using fsockopen, show the greeting screen, create the descriptor, then the MUD severs the connection, but without destroying the descriptor. The client and MUD will then communicate via input and output files (one acting as user input, the other as output for the client to display to the user). The files are named using the descriptor number and a short, randomly-generated passcode (both of which sent to the client before connection is severed) which serves to prevent accidental re-use of an old file and to deter would-be spammers from hyjacking it.

This premise would require minnimal alteration to the MUD itself with little or no loss of compatability (except maybe MSP or whatever :P), making it suitable for public release when it's finished.


Here's where I'm running into trouble. I close the connection (using closesocket as opposed to the close_socket function), and the descriptor is still there as it should be. Let's call it descriptor 16 (assuming I already have my admin character logged-in descriptor 15). Then, I connect to the MUD via standard telnet. I type 'users' on my admin character? I'm still descriptor 15, but BOTH the php and telnet users are using descriptor 16! When the PHP client connects, it sends 'new' before it's disconnected (just as a debug for now). When the second telnet user connects, it's already at the CON_GET_NEW_NAME section.

I've gone through every applicable line of accept_new, new_descriptor, init_descriptor, and game_loop, but everything I try (moving things around, ifchecks, manipulating the d->descriptor value directly by adding 1 to it for each PHP descriptor there currently is, etc) either causes a crash bug, causes problems in the initial connection such hanging, or has no effect whatsoever. The function (accept) that actually sets the 'desc' variable (which then becomes the integer value for d->descriptor) appears to be some internal compiler function, as I can't find it anywhere in the source. Therefore, I'm completely stumped as to what to do with it. The fact that this FD_SET and &in_set/&out_set/&exec_set stuff totally eludes me probably doesn't help much lol.


Anyways, if you've got any suggestions Nick (or anyone else who got any of this :P), I'm all ears. Anything that wouldn't require re-writing every section that loops through the descriptors (prolly like 90% of the MUD or so) would be extremely helpful =)
Top

Posted by David Haley   USA  (3,881 posts)  Bio
Date Reply #1 on Wed 29 Oct 2003 05:20 PM (UTC)
Message
I'm not sure that such a thing is possible. When the connection is closed, the descriptor is probably closed as well.

I do have to say that before you adventure down the socket path, you should read up on the socket functions and understand what the FD_SETs, the accept function, and all that good stuff means.

What exactly do you mean by "the descriptor is still there like it should be"? Do you mean your file, or what?

David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone

http://david.the-haleys.org
Top

Posted by Kris   USA  (198 posts)  Bio
Date Reply #2 on Wed 29 Oct 2003 05:24 PM (UTC)

Amended on Wed 29 Oct 2003 05:30 PM (UTC) by Kris

Message
No, I'm referring to the pointer itself. eg 'close_socket', which disposes of 'd', is not called as usual (closesocket is called directly instead). The goal, basically, is to make it realize that descriptor 16 (per this scenario) is in use, even though there is no active connection, so it will create the next descriptor as 17. :)
Top

Posted by David Haley   USA  (3,881 posts)  Bio
Date Reply #3 on Wed 29 Oct 2003 05:51 PM (UTC)
Message
Assuming you're running on Unix, closesocket refers to close... and the first paragraph of the man page for close is thus:
Quote:

close closes a file descriptor, so that it no longer refers to any file and may be reused. Any locks held on the file it was associated with, and owned by the process, are removed (regardless of the file descriptor that was used to obtain the lock).


I believe that Windows has almost identical behavior.

So, closing the socket like that just won't work... like I said, I'm really not sure how possible this is.

What you could do is try to not bother closing it, much like what copyover does. Keep the number in memory, and just have it keep writing to that descriptor.

Although I have to say that what you're doing is more than a little funky, and I really am not sure how possible it is.

David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone

http://david.the-haleys.org
Top

Posted by Samson   USA  (683 posts)  Bio
Date Reply #4 on Wed 29 Oct 2003 11:55 PM (UTC)
Message
Not to mention that this will generate untold amounts of memory leaks as DESCRIPTOR_DATA allocations will remain floating free in the mud to muck things up.

Isn't there some way you could have the mud create a dummy character to handle this sort of thing? And are you positive PHP is incapable of maintaining a socket? How else would such things as the Indigo codebase work if it coudln't.
Top

Posted by Kris   USA  (198 posts)  Bio
Date Reply #5 on Thu 30 Oct 2003 05:53 AM (UTC)
Message
In terms of maintaining an open socket, I'm positive; I spent two weeks trying to get that to work. The PHP manual, as well as every forum I found, said it's not possible. Basically, page output doesn't occur until after the script has terminated (default 30-second timeout). Once it's terminated, fsockopen closes the connection. So then I tried pfsockopen, hoping that a 'persistent' connection would do the trick. The socket didn't close when the script terminated, but I was unable to re-use that same socket later. I reviewed all the material I could find, and they said that pfsockopen in fact cannot be used for that, that in fact it is simply outside of PHP's current capabilities. This is due to the fact that, when the script terminates and restarts, it is done under a seperate process in Apache, and therefore cannot predictably re-use the socket connection created by the previous process of the script. They said it's simply not designed for such things, at least not currently.

As for keeping the socket open, that might just work; if I were to use pfsockopen and have the MUD send a string telling the php script to die(), thereby keeping the socket open but unused (since I'm not planning on using it again). That was my initial idea after re-using it was off the table actually, but I figured just having the connection itself terminated would be much cleaner.

But yah I'll try that approach when I get home and see if it works =)
Top

Posted by David Haley   USA  (3,881 posts)  Bio
Date Reply #6 on Thu 30 Oct 2003 06:34 AM (UTC)
Message
I glanced at the source code for the Indigo MUD (kyndig.com - code - search for indigo)... note that the PHP script actually stays alive, and never actually "dies" - therefore, the sockets stay persistent because the script process stays forever. It's quite a different concept, because the Indigo MUD doesn't have to output and input to and from a user. It's actually quite different from what you're trying to do here, because Indigo is a persistent server, whereas this PHP business is one-time-only.

Good luck in this... as I said, I doubt it's possible. You need some kind of persistent environment to keep the socket alive. Too bad you can't use a java telnet client. (Your work must have a REALLY tight firewall. :P)

Can you use SSH port forwarding from work? You may have better luck that way...

You could probably write a PHP "script" that reads from stdin and writes to stdout, but such a thing would need to run on the same physical machine as the server, so you'll need access to that.


No matter what crazy idea I come up with (and I came up with a few... :P) it just seems that you need to connect to the remote server (where the MUD is) through a non-standard port, because the other ones are already in use.

David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone

http://david.the-haleys.org
Top

Posted by Kris   USA  (198 posts)  Bio
Date Reply #7 on Thu 30 Oct 2003 06:38 AM (UTC)
Message
I love a challenge hehe. If/when I get it finished and ready for release, I'll send you a copy =)
Top

Posted by Nick Gammon   Australia  (23,173 posts)  Bio   Forum Administrator
Date Reply #8 on Sun 02 Nov 2003 08:22 PM (UTC)
Message
I think my earlier recent suggestion of an HTTP client would work better than this, to sneak past a firewall, but whatever. :)

I suggest making no changes to the MUD, which sounds like they aren't working anyway, however to interpose a small "redirector" program between the server and the PHP program.

Something like this:

The PHP session starts - and you somehow recognise a new session - and the PHP code on the server end starts up a copy of the redirector program on the server end. This takes input (and writes to output) as disk files, and also establishes a connection to the MUD via TCP/IP, like this roughly:

PHP --> (disk file) --> redirector program --> TCP/IP --> MUD

The redirector program stays running and the MUD thinks it is talking to that, so it is happy (it connects to "localhost").

Then as a command arrives to the web page (PHP) it writes a new disk file, the redirector program finds the file date has changed (or whatever method) and sends the command to the MUD. When it gets a response it writes it out as an "output file" which the PHP program detects and sends back to the user.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).

To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.


28,889 views.

It is now over 60 days since the last post. This thread is closed.     Refresh page

Go to topic:           Search the forum


[Go to top] top

Information and images on this site are licensed under the Creative Commons Attribution 3.0 Australia License unless stated otherwise.