Skip to text skip




Socket programming in PHP.

In almost any high-level programming language there exists pre-defined functions that allows you to create, write and listen on sockets. In PHP, these functions are already included in the standard library. There are many popular extension available that allows you to work with sockets in PHP (e.g. cURL), this document will however treat PHP's fsockopen()-method since it is accessible on almost any system that has been compiled with a normal PHP build. But before jumping into the practical part; a quick introduction to what sockets are.

Basics about sockets

To put it simple, a socket, in computer terms, is a virtual circuit between two hosts over a IP-oriented network. TCP/IP is the communication-model that will handle routing and transferring of data between both end points of the socket. When data arrives to one of the end points, the application layer takes care of passing it on to the service that listens on a specific port, which in turn will do whatever is necessary for that socket (this is protocol specific). Hostname/IP-address and port number is mandatory in order to establish sockets. The port number indicates what service/process that should handle the socket in the end points. Computers whose services are offered constantly (servers) often listens on the same port, whilst the clients that connect to them uses a new port number for each socket connection. The more common services listen on port numbers from 1 through 1024, and other services goes from 1025 through 65535. For instance, port 80 is often used by services that handles HTTP-requests, whilst port 1337 may be used for an application you wrote yourself.

Here is a common syntax when presenting a one-way socket:

protocol://hostname:port
E.g.: http://solecki.se:80 or ftp://127.0.0.1:21

Practical use of sockets in PHP

As mentioned in the beginning of this entry, you can write and listen (read) to sockets. This is because on UNIX-like operating systems sockets are handled as files, and PHP handles them in the same way. The reading and writing works pretty much just as when reading/writing to any file on a secondary storage, except now the "files" are allocated to the primary memory (usually some kind of RAM) and the data streams goes over a TCP/IP-connection (socket). If you have worked with reading/writing to files in PHP before, you will easily follow and understand what happens in the source code below. Either way, I will recap the source (instead of fully commenting it).

The fsockopen()-method:

resource fsockopen  ( string $hostname  [, int $port [, int &$errno  [, string &$errstr
[, float $timeout ]]]] )
<?php

$host = '81.216.171.106';
$port = 80;
$streamSize = 128;

# try to init a new socket
$sh = fsockopen($host, $port);

if ($sh) {
	# write a custom data stream through the socket
	fwrite($sh, "GET / HTTP/1.1\r\nHOST: $host\r\n\r\n");
	echo 'Retrieving data...' . "\n";

	while (!feof($sh)) {
		# allocate the incoming data stream to the variable $data
		$data .= fread($sh, $streamSize);
	}

	# close the connection
	fclose($sh);
	var_dump($data);
}
else {
	die('Error...');
}

?>

Quick walk through of the above code: At first I declare three variables for ease of potential further use of the script. Then the fsockopen()-method tries to create a new socket to the host $host on port $port. If it succeeds, the $sh variable will hold the memory to the resource, and it will later be used as our "file". After calling the fsockopen()-method, we test the status of our potential socket to see if it could initialize properly. If it did not return a boolean datatype FALSE, it means our socket was successfully created, and the interpreter can continue in the "if" code block. And the reason for using the fsockopen()-method instead of just fopen()? Well, the fsockopen()-method simply gives you more freedom. The fopen()-method would in this case (port 80) just send a HTTP GET request to the socket, with fsockopen() however, we can send our own hand-crafted data streams etc..

Next, inside the if code block, we use the fwrite()-method to write whatever we want to our created socket. As for this script, I choose to write a HTTP-request, requesting the root (/) at $host.

Then in the following "while" code block, we check if the file pointer is not at the end of file (EOF) with the feof()-method. This method will return TRUE when the file pointer is at the EOF. While it is not (notice the exclamation mark in the while()-method's input), PHP will interpret the while-loop and from there we will call the fread()-method to read data off the socket and allocate it to the variable $data.

And that is pretty much it, a script that communicates over TCP/IP-oriented networks and interacts with HTTP. This is basically all you need to write your own network dependent programs. But if you still do not feel satisfied, the PHP manual will give you enough rope to hang yourself. Just remember that you can, of course, choose to work with other protocols such as IRC, telnet or maybe your own protocols.

Posted on Aug 17th 2008 04:18:22 GMT-02 clock Leave a comment! (2)

Back to the top


A few site updates.

I have made a few website updates just recently, not too many, but still something. Anyhow, the updates consist of me adding the search.php-file that has been linked in the menu since the launch of the website. If you have tried to access it before today, you would have received a 404 response-header from HTTP, and additionally a 404-page. Fortunately this is not the case anymore. The search.php-file is working as expected and it might come in handy later when the database is filled with more rows of my entries.

I have also added a captcha-system to prevent malicious bots from filling my secondary storage with junk. The captcha-system is very simple, it consists of a image with a randomly generated string which needs to be filled in to the comments form in order for you to post comments. It is admittedly not the most secure captcha-system, but I did not feel like putting much effort at all into something that however probably would not be exploited.

The content in the about.php-file has been altered, but it is just a few bytes of gibberish. Check it out if you are bored or so.

And lastly, I added a meta-tag with the http-equiv attribute "Content-Type" sending the value "application/xhtml+xml", and hopefully the markup language will be delivered and rendered as a XML by the user-agents.

Posted on Jul 1st 2008 03:17:17 GMT-02 clock Leave a comment! (2)

Back to the top


RSS 2.0 feed available.

I have added a RSS feed which is available for subscription.

RSS (Really Simple Syndication) makes it possible for you to very easily keep updated with this website's dynamic content. To check if a new entry is posted you will just have to consult your RSS reader, instead of visiting the website, download all the files related to it and then check whether the website has been updated or not.

To subscribe on the RSS feed you will probably (this differs from different web browsers) simply have to click the link in the menu named RSS feed, and then follow the instructions. If your web browser does not have support for RSS reading, or you do not like the built-in one, you will have to download an external RSS reader. There are plenty of free RSS readers available on the Internet, use a search engine such as google to find one you like.

Posted on Jun 10th 2008 06:39:24 GMT-02 clock Leave a comment! (9)

Back to the top


A quick look at IPv6.

IPv6, short for Internet Protocol Version 6, is the "next generation" protocol, the successor of IPv4. The main reason why we would need support for the IPv6 is because of the lack of IP addresses. Today we are in a situation were allocation of public IP addresses is at its last breath, and that is why we need IPv6 implementation. Techniques such as NAT is one of the reasons why the Internet infrastructure is still working. If every host that hides behind a masquerading network would obtain a public IP address, the number of available IP addresses would have been exceeded a long time ago.

NAT, which is a commonly used technique, allows hosts in private class A, B and C networks to connect to the Internet through a gateway (usually a router), using only one public IP address. While this is working fine for the end users today, it is actually kind of an emergency solution to the problem, and it causes lots of extra work to be done. Routers and other network devices needs to be configured to work with the NAT technique. Henceforth NAT also has apply its purpose, to translate local private addresses into public ones on outgoing sockets. With IPv6 however, this will not be an issue since address translation techniques will be redundant cause of the huge amount of available addresses, which pretty much is the main feature of IPv6—its wide address space.

IPv6 versus IPv4

IPv6 has support for up to 2^128 IP addresses. This is an extremely big increment relatively to the prior IP-standard, version 4, which "only" supports 2^32 IP addresses (i.e. ~4.3 billion addresses). 2^128 addresses, that is pretty much, you think. And yes, indeed it is. Written on decimal form it adds up to a number about this big: 340282366920938000000000000000000000000. A pretty massive number, is it not? Individual people will be able to own as many addresses as is available for the Internet today. In other words; networks with the size of today's Internet will be available for private persons.

Physical structure

IPv4 addresses consist of 32 bits (4 bytes/octets). Human readable the IPv4 addresses are written in pointed decimal form (a.k.a. dotted quad syntax), e.g:

IPv4
	Decimal:	81.216.171.106 # humans

	Binary:		01010001 11011000 10101011 01101010 # computers
			

The IPv6 addresses although differs quite a bit from the ones used in version 4. IPv6 addresses consists of 128 bits (16 bytes/octets), i.e. physically 4 times as big relatively to the IPv4 addresses. Human readable it is written in hexadecimal form, grouped into segments of 4 bytes that are separated by colons (colon-separated quad syntax). The fact that IPv6 addresses are written in hexadecimal form is just great. Me and almost certainly everyone find it much easier to convert hexadecimal values into binary rather then from decimal to binary.

Here is an example of an IPv6 address:

IPv6
	Hexadecimal:	ca12:b9fa:655a:0000:0000:ac2f:ccef:f0ab # humans

	Binary:		11001010 00010010 10111001 11111010 11001010 01011010
			00000000 00000000 10101100 00000000 00000000 00101111
			11001100 11101111 11110000 10101011 # computers

As you can see in the address above two 4-byte-segments only consists of zeros. When that occurs that/those block(s) can be omitted and replaced with a double colon. Hence the address above could have been written as: ca12:b9fa:655a::ac2f:ccef:f0ab. Repetition of the double colons however is not permitted, the address will then be invalid since it becomes obscure how many 4-byte-segments of zeros that exists.

Another good thing about IPv6 is that it will not handle errors (I am not referring to errors such as the ones ICMP handles, although that is just an help protocol for IP, if you believed something else), instead it will rely on error handling at the data link layer. For example, in IPv4 the routers have to recompute the checksum in the IP-header since fields such as the TTL-field changes during transport over new hops/metrics. This will not be an issue with IPv6 and routers will save the CPU-powers of theirs.

Subnetting

Complex subnetting schemes will not be needed with the superfluous purpose of increasing the number of hosts in a network. This is really great since it will eliminate unnecessary work that is just in the way for the real purpose of subnetting; to speed up traffic with faster routes using logical segmentation.

Anyhow, these are just a few of the benefits that comes with IPv6. If you feel tempted to try it today you can visit useipv6.com. And if you want to read more detailed information about IPv6 i suggest you read the IETF's RFC about it.

Posted on Jun 4th 2008 05:10:51 GMT-02 clock Leave a comment! (0)

Back to the top


Using a fixed width on inline elements with CSS.

If you want to use a fixed width with css, versions greater than 2.1, on a inlined *ML element, you would just use the value inline-block, and that is it. However, support for CSS greater than, or equal to level 2.1 has not yet been implemented in most web browsers, hence there is not much support for the inline-block value. And if you are simply trying to use display:inline; the values of the width property will be set to 0.

So how do you bypass this then?

Well, to achieve that the inline elements would be displayed with a fixed width, we can just use the float property.

#foo .bar {
	display:inline;
	float:left;	/* this will "override" display:$value; */
	width:30px;
	background:#FF0000;
	margin:10px;
}

And now you have got your .bar classes, with fixed width, in line, just as if they were elements with the display:block value. This will apply to all the .bar classes within the #foo div element id.

Posted on Jun 2nd 2008 05:39:50 GMT-02 clock Leave a comment! (2)

Back to the top


Website launch!

Well... welcome.

I have uploaded the websystem files to my server, it is up and running, fully available for the public, and there is really not much more for me to write here. If there would be anything else you want to know about this website I have written a short description about it. You can access the file through the link or the menu.

Since it looks so empty without any real content I will be posting a new entry soon, and hopefully I will continue in doing so later on. Worth to notice is that the images are around 500 kilobytes in file size, which will cause a small delay in the page load time since my ISP provides an upload rate of ~100kbit/s. Anyways, that is about it. Feel free to leave a comment if you desire.

Posted on Jun 1st 2008 18:47:40 GMT-02 clock Leave a comment! (6)

Back to the top


Index|About|Search

Copyright © Adam Solecki Söderberg 2008 | XHTML 1.0 | CSS 2.1 | Nothing on this website may be redistributed without my permission | Email me email icon