Home arrow PHP arrow Sockets and PHP
PHP

Sockets and PHP


If you are an intermediate PHP developer you may have wanted to use sockets in connect to your FTP server. Demitrious shows you how this is done.

Author Info:
By: Demitrious Kelly
Rating: 4 stars4 stars4 stars4 stars4 stars / 35
March 25, 2003

print this article
SEARCH DEVARTICLES

If you are an intermediate PHP developer you may have wanted to use sockets in connect to your FTP server. Demitrious shows you how this is done.

Sockets have long been important to the underlying nature and structure of things in, on and around computers. They are very powerful. PHP allows you to harness them at the expense of a couple of late nights, and many cans of liquid caffeine yet, it seems, that too few people truly understand sockets.

I suppose that before you can really use any functionality of sockets it's important to define what sockets are. A beginner should read this for sure, but learned folk (yea I just called all you l337 hax0rs out there 'folk', get over yourselves!), would only need this to refresh their memories as to what sockets are and what they mean.

What are sockets?

A socket is a lot like a pipe or a hose. It is meant to have matter travel through it. This "pipe" does not care what kind of matter will go through it, going through it or already went though it. Nor does it care where the matter is coming from or where it is going to. It's only encompassing goal is to let that matter through it. You can consider a socket (on a computer) to be the pipe which carries the data through it.

Lets take a pathetic example of browsing the web - a task that most of us take for granted. Think about it:

1) You open your web browser, and say "yonder to www.apokalyptik.com !"

2) Your web browser responds by asking the operating system to make a socket connection to " www.apokalyptik.com ."

3) From there, to be short, your OS (Operating System) uses the socket that it just created to the remote server's socket that is 'listening' on port 80.

NOTE: I simplified this considerably. If I would write all the steps in details then it would be about 17 pages long.

4) When the connection has been successfully established the 'data' (web page) can then flow through the pipes (sockets) and we can see it.

Is this the say-all and end-all of sockets? Of course not!

Log into any Unix box and type netstat -an - you will see a list of TCP sockets, UDP sockets, Active UNIX domain sockets (both, servers and established) and staff like that..

There are two reasons I can see for using a Unix socket.

1) You find that the PHP built-in functions do not suite your needs.

2) You want to make your own service with its own protocols

In any of these cases PHP accommodates you by allowing you to manipulate data at the service level, and bypass all of the middle men.

How exactly does one go about exploiting sockets for fun and profit? Start with a careful planning and lots of research! Is it a bit of work, true, but are the rewards worth it!

Case 1: You are interested in connecting to a service which PHP does not fully support, or you are not fully happy with its support.

Step 1: Choose a service

For this example I will choose a common protocol: FTP. It's not the easiest of the protocols to grasp, but afterwards, you should have a much keener grasp on how all of this works.

Step 2: RTFM RTFM RTFM RTFM

You cannot just expect things to magically work for you - you need to put some serious thoughts into how the service works, what you want from it and how you plan to make it working.

Go to www.google.com and search for your service and the word (acronym) RFC (which stands for 'Request For Comment'). When we do this we get good info like: http://www.ietf.org/rfc/rfc959.txt .

Reading this we find all the commands and rules that an FTP server and an FTP client must obey... Here's a brief and important summary. You have to use 2 sockets for most of your communications with the server. You have a control socket (commonly port 21) and a data socket (commonly port 22).

To make things even more difficult for you (relax, I know what I'm doing) I proclaim that we will use PASSIVE mode FTP (see: http://slacksite.com/other/ftp.html for further details on what, exactly, passive mode is...)

Step 3: Think Things Through!

Well now we've got a lot to deal with variables, commands and the like... Let's try to keep things clean. We'll make a class for our FTP client. (see: Object Oriented John (Intro to Objects), one of my previous articles on PHP Beginner). All we want to do is log in, get a directory listing and log back out.

To do this we need to be using the following variables:

1. host name
2. port number (default 21)
3. username (default anonymous)
4. password (default
e-mail@email.com )

To do this I figure we need the following functions

1. control_socket()
2. data_socket()
3. login()
4. passive()
5. ftp_list()
6. logout()
7. cmd_status()

We also need to keep track of the following:

1. whats going out and coming in on the control socket

2. whats coming in on the data socket (we never write anything to it)

Step 4: Putting Things Together

We'll start by defining our FTP class

<?php
    class ftp {
        // Here is the skeletone of our ftp class. A shining beacon
        // of light in an otherwise desolate landscape of socket code....
        // The hostname of the computer we are going to connect to
        var $hostname;
            // The port number we will connect to on the host.
            // Not always port 21
        var $portnumb;
            // The username and password we will use to log into
            // the FTP site with (In case we're accessing a private server)
        var $password;    
        var $username;
            // The variable containing the control socket pointer
        var $contsock;
            // The variable containing the data socket pointer
        var $datasock;    
        function control_socket_reset() {
            // This function will reset the socket variables so that we
            // can use it again (in essence, we're providing our control
            // socket with a strong cup of coffee to keep it awake)
        }
        function control_socket($host, $port) {
            // This function will establish our 'control' connection
            // to the ftp server. This is the connection that we will
            // give all of our commands to...
        }
        function data_socket($host, $port) {
            // This function will establish our 'data' port which
            // will return any data that our commands provide.
            // in this example we will only enable this AFTER we've
            // passive()'d
        }
        function login($username='anonymous',
$password='e-mail@e-mail.com' ) {
            // This will log us onto the ftp server. it will use either
            // the default anonymous login information, or info that you
            // call the function with
        }
        function passive() {
            // This function will get everything ready for us to set up our
            // data socket, and then actually initiate it by calling
            // data_socket($host, $port);
        }
        function ftp_list() {
            // This will get the directory listing that we want. This one
            // little function is causing us to do all this work. Such is
            // life. Often it's the little stupid things which you're boss
            // will have you work on for hours on end, while more pressing
            // issues fall by the wayside (it's, of course, your fault when
            // that happens ;)
        }
        function cmd_status() {
            // This code will find out whether a command was completed
            // successfully or not (very useful!)
        }
        function logout() {
            // Since we want to be good little net'zines we'll properly log
            // ourselves out of the server when we are finished... (what...
            // were you born in a barn?!)
        }
    }
?>

PHEW! Was that a lot to grasp? that's ok... take some time... grab some aspirin, and a snack... Let the information soak in for a while, before moving on... You need to approach this topic with a clear mind, and a willingness to go the distance! (I SAID it would be some work...)

Step 5: building our first connection

Every journey begins with the length of a single step. It's now time to build our control socket. Don't worry, it's easier then it sounds...

<?php
    function control_socket($host, $port) {
            // Store variables here just in case. We need them
            // at some later time (I know that we will not in this article,
            // but good record keeping has saved MANY a good programmer
        $this->hostname = $host;
        $this->portnumb = $port;
        $this->contsock = fsockopen($this->hostname, $this->portnumb);
            // establish the connection and keep it to find later again
        
if ( $this->contsock ) {
            Return True;    // Return TRUE if our connection was successfull
        }
        else {
            Return False;    // Return FALSE if we failed!
        }
    }
?>

Wasn't that simple? Realistically, it was a single function with some code thrown in to make sure that commection happened. It is always a good idea to check whether things go wrong, so we can close up any loose ends.

ACK! Now we need to test! I generally believe that it's a very good idea to test your code at every point. It may be a little bit more time-consuming, but in the end, you end up with a more reliable, bullet-proof code and less bugs. We will throw this down to the bottom of our code.

<?php
    $ftp = new ftp;
     if ( $ftp->control_socket('ftp.cdrom.com', 21) ) {
        echo 'We have successfully connected!<br>';
    }
    else {
        die('We have failed to connect!<br>');
    }
?>

After testing it carefully we see that out control connection code works! Congratulations! But don't get carried away with yourself just yet - there's more difficulties to come then you, as of yet, understand!

Step 6: Our daily dose of caffeine

I'm going to let you in on a little secret which no one seems to know (or no one seems to want to share). Normally, when you fopen() a file, fgets() will return either something or an error, but when you open a socket with fsockopen(), fgets() will wait..., wait..., wait..., wait... and wait for something to be in the buffer. This SERIOUSLY slows application down. There is nothing, nothing with the fsockopen() docs in relation to this problem - nor even a mention of it. You need to use the socket_set_timeout() function that allows you to set a timeout with milliseconds resolution for fgets() on a socket. Tuck that info away in your PHP toolbox, you might need it some day!

Want to know another secret? After you've timed out a socket (using fgets() and socket_set_timeout()) it stays timed out until you reset it again with socket_set_timeout(). No one seemed to know the answer to this little problem either, so store it away, because the likelyhood of you finding the answer when you most need it is very low :)

With this in mind, we're going to setup our 'caffeine' function, control_socket_reset(), which will set our sockets timeout to a manageable 3 seconds.

<?php
    function control_socket_reset() {
        if ( $this->contsock ) {
                // Reset (or set) the timeout on our control socket
            return True;
        } else {
            return False;
        }
    }
?>

With all this, you should be alble to connect to your FTP server. In the next week's article I will desribe how to login on your server, and pulling the data in and out of the FTP server using sockets!


DISCLAIMER: The content provided in this article is not warranted or guaranteed by Developer Shed, Inc. The content provided is intended for entertainment and/or educational purposes in order to introduce to the reader key ideas, concepts, and/or product reviews. As such it is incumbent upon the reader to employ real-world tactics for security and implementation of best practices. We are not liable for any negative consequences that may result from implementing any information covered in our articles or tutorials. If this is a hardware review, it is not recommended to open and/or modify your hardware.

All PHP Tutorials
More By Demitrious Kelly


blog comments powered by Disqus
PHP ARTICLES

- Removing Singletons in PHP
- Singletons in PHP
- Implement Facebook Javascript SDK with PHP
- Making Usage Statistics in PHP
- Installing PHP under Windows: Further Config...
- File Version Management in PHP
- Statistical View of Data in a Clustered Bar ...
- Creating a Multi-File Upload Script in PHP
- Executing Microsoft SQL Server Stored Proced...
- Code 10x More Efficiently Using Data Access ...
- A Few Tips for Speeding Up PHP Code
- The Modular Web Page
- Quick E-Commerce with PHP and PayPal
- Regression Testing With JMeter
- Building an Iterator with PHP

Watch our Tech Videos 
Dev Articles Forums 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
Contact Us 
Site Map 
Privacy Policy 
Support 

Developer Shed Affiliates

 




© 2003-2017 by Developer Shed. All rights reserved. DS Cluster - Follow our Sitemap
Popular Web Development Topics
All Web Development Tutorials