The TcpClient class wrappers the networking details for reading/writing to a network stream into a simple, easy-to-use class (much like .NET TcpClient). An example use, connecting to a POP mail server, is attached. Change the POP server details and username/password at the top of the file to test.
By : wmfwlr
<!-- EXAMPLE SCRIPT USING CLASS -->
<font face="verdana" size="2">
<?
include('class.TcpClient.php');
//** Displays the error message given if there is non-empty text.
function ShowError($errortext)
{
if(strlen($errortext) > 0)
print("<font color='red'>$errortext</font><br>");
}
//** the POP server address, user account, and password to use for
//** testing client application. NOTE: your POP user name is your
//** full email address, unless the server is otherwise configured.
$PopServer = "popserver.yourdomain.com";
$PopUser = "email@yourdomain.com";
$PopPassword = "yourpassword";
//** connect to the POP server given on 110, the standard POP port.
//** Change this if necessary.
$client = new TcpClient($PopServer, 110);
//** set the default read/write timeout to 2 seconds (2000 ms).
$client->Timeout = 2000;
//** you can set the default newline character(s) used when sending data.
$client->NewLine = "\r\n";
//** connect to server and get any error message (if available).
$client->Connect();
ShowError($client->GetError());
//** get the mailserver greeting (one line).
print("<b>" . $client->ReadLine() . "</b><br>");
ShowError($client->GetError());
//** send user login info to the server.
print($client->WriteLine("USER $PopUser") . " bytes written<br>");
ShowError($client->GetError());
//** get the mailserver USER response message.
print("<b>" . $client->ReadLine() . "</b><br>");
ShowError($client->GetError());
//** send user account password to the server.
print($client->WriteLine("PASS $PopPassword") . " bytes written<br>");
ShowError($client->GetError());
//** get the mailserver PASS response message, login success
print("<b>" . $client->ReadLine() . "</b><br>");
ShowError($client->GetError());
//**!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//**!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//**
//** Put any other commands for the POP server here!
//** Full command list @ http://www.ietf.org/rfc/rfc1939.txt
//**
//**!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//**!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//** notify the mail server connection is closing.
print($client->WriteLine("QUIT") . " bytes written<br>");
ShowError($client->GetError());
//** get the mailserver farewell message.
print("<b>" . $client->ReadLine() . "</b><br>");
ShowError($client->GetError());
$client->Close();
?>
</font>
<?
//-- CLASS FILE FOR TCP CLIENT --
//** ©William Fowler (wmfwlr@cogeco.ca)
//** DECEMBER 22/2003, Version 1.0
if(isset($GLOBALS["tcpclientclass_php"])) { return; } //** include once.
$GLOBALS["tcpclientclass_php"] = 1; //** file included.
//** error code indicating that no connection is available.
define("TcpClientNoConnection", 0);
//** the default number of milliseconds to wait before timing out.
define("TcpClientDefaultTimeout", 30000);
//** the minimum buffer size for the TCP client class.
define("TcpClientMinBufferSize", 256);
//** the default newline character(s) used.
define("TcpClientNewLine", "\r\n");
//**!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//**TCP_CLIENT_CLASS_DEFINITION***********************************************
//** The TcpClient class encapsulates most networking communication details
//** into an easy-to-use wrapper. Connections are not persistant.
class TcpClient
{
//** (Integer) the internal underlying socket identifier.
var $Socket = TcpClientNoConnection;
//** (String) the name/IP of the remote host
var $Host;
//** (Integer) the port number to connect to remote host.
var $Port = 0;
//** (String) the last error that occurred (NULL if no error).
var $LastError = null;
//** (String) the newline character to be used when sending data.
var $NewLine = TcpClientNewLine;
//** (Integer) the size of the buffer used to receive data.
var $ReceiveBufferSize = TcpClientMinBufferSize;
//** (Integer) the number of milliseconds to wait before aborting a connect,
//** read, or write operation for the client.
var $Timeout = TcpClientDefaultTimeout;
//** creates a new TcpClient instance based on the hostname and port given.
function TcpClient($remoteHost=null, $portNum=0)
{
$this->Host = strval($remoteHost);
$this->Port = intval(max(0, $portNum)); //** ensure port >= than zero.
}
//** Returns: Boolean
//** Determine whether or not a connection to the remote host has been
//** established.
function isOpen()
{
return ($this->Socket ? true : false);
}
//** Returns: String
//** Get the last recorded error that occurred. If no error previously
//** occurred NULL is returned. The last error is cleared.
function GetError()
{
$theerror = $this->LastError;
$this->ClearError();
return $theerror;
}
//** Returns: None
//** Clear the last error stored for this client.
function ClearError()
{
$this->LastError = null;
}
//** Returns: Boolean
//** Attemept to connect to the client remote host on the port number given.
//** If no host is available FALSE is returned and no connection is made.
//** If FALSE is returned the last error is available from the 'GetError()'
//** method.
function Connect()
{
$this->ClearError(); //** clear any existing error messages.
//** no host name/IP has been set for this client, no connection can be made.
//** Store the appropriate error.
if(strlen(trim($this->Host)) == 0)
{
$this->LastError = "No remote host was provided";
return false;
}
//** attempt to connect to the host on the port given. Record any error number
//** and error message generated.
$errorNum = 0;
$this->Socket = fsockopen($this->Host, $this->Port, &$errorNum,
&$this->LastError, ($this->Timeout / 1000));
//** if there is no error given and the socket is valid connection is okay.
return ($this->isOpen() && strlen(trim($this->LastError)) == 0);
}
//** Returns: Boolean
//** Attempt to close the open client connection.
function Close()
{
//** no open cobnnection is available. Set error appropriately.
if(!$this->isOpen())
$this->LastError = "No connection available to close";
//** an open connection is available to close. Close underlying socket.
else
{
fclose($this->Socket); //** clsoe the connection.
$this->Socket = TcpClientNoConnection; //** no connection now.
}
return !$this->isOpen(); //** return the close operation success.
}
//** Returns: Integer
//** Attempt to write the data given to the underlying socket. The number of
//** bytes successfully written to the stream is returned. If no connection
//** is available 0 is returned, as no bytes were written.
function Write($data=null)
{
//** no connection is available, zero bytes can be sent.
if(!$this->isOpen())
{
$this->LastError = "No connection available for writing";
return 0;
}
$data = strval($data); //** ensure that data is available.
if(strlen($data) == 0) //** no data to be sent.
return 0; //** zero bytes were sent.
else //** connection and data, set timeout and send.
{
$this->_SetTimeout(); //** set timeout.
return fwrite($this->Socket, $data, strlen($data)); //** write data.
}
}
//** Returns: Integer
//** Attempt to write the data given to the underlying socket, followed by a
//** newline. The newline is defined by the '$this->NewLine' property. The
//** number of bytes actually written is returned.
function WriteLine($data=null)
{
return $this->Write($data . $this->NewLine);
}
//** Returns: String
//** Attempt to read the number of bytes given (or one by default) from the
//** connection. If no connection is available, the length given is zero or
//** negative, or an error occurs NULL is returned.
function Read($length=1)
{
if(intval($length) <= 0)
{
$this->LastError = "Cannot read zero or less bytes";
return null;
}
//** no connection is available to read from, no data can be read.
else if(!$this->isOpen())
{
$this->LastError = "No connection available for reading";
return null;
}
else //** a valid connection identifier is available.
{
$this->_SetTimeout(); //** ensure timeout is set.
return fread($this->Socket, $length); //** attempt to read n-bytes.
}
}
//** Returns: String
//** Attempt to read one full line from the underlying stream. If no
//** connection is available NULL is returned. Any newline characters
//** are included in the string returned.
function ReadLine()
{
//** no connection is available to read from, no data can be read.
if(!$this->isOpen())
{
$this->LastError = "No connection available for reading";
return null;
}
//** continue to read in data until a line ends with the newline character(s).
//** This is safe as the 'fgets()' function will not read past a newline
//** character. Ensure that the read buffer is at least the minumum size. If
//** one iteration is complete and no data was read in the socket blocking
//** expired. Stop reading at that point.
$streamdata = ""; //** no data to start with.
$sockethasexpired = false; //** initially no timeout experienced.
while(!$this->_EndsWithNewLine($streamdata) && !$sockethasexpired)
{
$this->_SetTimeout(); //** ensure socket timeout is set.
$streamdata .= fgets($this->Socket, max(TcpClientMinBufferSize,
$this->ReceiveBufferSize));
//** if ever at the point where reading has occurred and no data is available
//** a socket timeout has occurred. Exit the loop and set the error.
if(strlen($streamdata) == 0)
{
$sockethasexpired = true;
$this->LastError = "The read took longer than $this->Timeout ms";
}
}
return $streamdata; //** return the data received, including newline.
}
//** Returns: Boolean
//** Determine whether or not the string given ends with a newline character.
//** If no data is given FALSE is returned.
function _EndsWithNewLine($data=null)
{
$data = strval($data); //** ensure that data is a string.
if(strlen($data) == 0) //** no date given to test.
return false; //** does not end with newline.
//** get the position of the last newline character. If the value returned
//** is not numeric it is a boolean, indicating no match. Considered to end
//** with newline if it ends with either a '\n' or '\r' character.
$creturnpos = strrpos($data, "\r"); //** position of '\n'.
$newlinepos = strrpos($data, "\n"); //** position of '\r'.
return (is_int($newlinepos) || is_int($creturnpos));
}
//** Returns: None
//** Set the underlying socket timeout to the 'Timeout' value for this
//** instance. If not connected nothing is done.
function _SetTimeout()
{
//** if a connection is available set the socket timeout. Get the number of
//** seconds and microseconds form the instance 'Timeout' property.
if($this->isOpen())
{
stream_set_timeout($this->Socket, intval($this->Timeout / 1000),
intval(($this->Timeout % 1000) * 1000));
}
}
}
?>
| 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. |
More Miscellaneous Code Articles
More By Codewalkers
developerWorks - FREE Tools! |
Visit IBM developerWorks to download a free trial version of Lotus Quickr 8.0, which enables collaboration by transforming the way everyday business content such as documents, rich media, photos, and video can be shared. Lotus Quickr makes it faster and easier to share content of all types (not just documents) within virtual teams. It is designed to make it easier to collaborate across organizational boundaries, while continuing to work within the context of familiar desktop applications. FREE! Go There Now!
|
|
|
|
Get a free trial download of the latest version of IBM Rational Performance Tester V7.0.1, a load and performance testing solution for teams concerned about the scalability of their Web-based applications. Combining multiple ease-of-use features with granular detail, Rational Performance Tester simplifies the test-creation, load-generation and data-collection processes that help teams ensure the ability of their applications to accommodate required user loads. FREE! Go There Now!
|
|
|
|
As organizations integrate software into every aspect of business, they are constantly pressured to deliver faster, better, and cheaper results. Unfortunately, a “dis-integrated” software delivery approach reduces returns while increasing costs. This IBM Rational White Paper shows how Integrated Requirements Management aligns organizations around maximizing value and keeping pace with change. FREE! Go There Now!
|
|
|
|
Manage, govern, and share services across your organization by using WebSphere Service Registry and Repository. Follow the hands-on exercises to learn how to navigate the Web interface to publish, find, reuse, and update services. FREE! Go There Now!
|
|
|
|
Join this Rational Talks to You teleconference on December 4 at 1:00 pm ET to discuss how Rational Method Composer can help meet your compliance objectives. Get your questions answered! FREE! Go There Now!
|
|
|
|
Learn how you can extend modern application lifecycle management to IBM System z through the IBM Rational Software Delivery Platform (SDP). The Did you say mainframe? e-kit includes podcasts, webcasts, tutorials, white and red papers, demos, and articles designed to help ease the challenges of modernizing your enterprise. This complimentary kit for mainframe developers is a practical, how-to guide for making the most of an existing development environment, including the skills and infrastructure already in place at an established enterprise. FREE! Go There Now!
|
|
|
|
In this tutorial, you can learn how to install and configure the IBM Rational Asset Manager Eclipse client, explore the different views in the Asset Management perspective, learn various search techniques, work with existing assets, and submit a new asset. FREE! Go There Now!
|
|
|
|
Learn the basics of the IBM Customer Information Control System (CICS). With a hands-on exercise, learn how to get your first CICS application up and running on your desktop using TXSeries V6.1 for Windows. The tutorial shows you how to download and install a free trial version of TXSeries V6.1. FREE! Go There Now!
|
|
|
|
Download a free trial version of IBM Rational Developer for System i V7.1, which provides a complete development environment for traditional i5/OS application development. IBM Rational Developer for System i is a new eclipse-based workstation offering for i5/OS application development that provides a comprehensive Integrated Development Environment for edit/compile/debug of traditional RPG/COBOL/C/C++ i5/OS applications. FREE! Go There Now!
|
|
|
|
David Barnes, Lead Evangelist for IBM Emerging Internet Technologies will discuss aspects of Web 2.0 that bring value to corporations, academia, and government. He'll also discuss IBM's vision around Web 2.0, including the importance of remixability and consumability. The discussion will culminate with examples of various IBM Software Group solutions you can use to get ahead of the Web 2.0 adoption curve. FREE! Go There Now!
|
|
|
|
All FREE IBM® developerWorks Tools! |