|
Taking
up from where we left off last week, let us now write the
code that should get executed when a client clicks the Connect
As Client button. The bclient_Click( ) handler is given
below.
private void bclient_Click (object sender, System.EventArgs e)
{
String servername = tserver.Text ;
int portno = Convert.ToInt16 ( port.Text ) ;
tc = new TcpClient( ) ;
try
{
tc.Connect ( servername, portno ) ;
}
catch ( Exception ex )
{
MessageBox.Show ( Cannot connect to server ) ;
return ;
}
bclient.Enabled = false ;
}
Here, we have firstly obtained the server name and port number.
In the next statement we have created an object of the TcpClient
class. Using this object we have called the Connect( ) method
and passed to it the server name and port number. The Connect(
) method would send the connection request to the server specified
by the server name at the port specified by the port number.
The Connect( ) method would wait until the server accepts
the connection. Lastly, we have disabled the Connect
As Client button. The client can now enter and send
the file name to the server. The handler for the Open
button is given below.
private void bopen_Click ( object sender, System.EventArgs e )
{
string s = fname.Text ;
s += * ;
byte[ ] buf = new byte [ s.Length ] ;
buf = Encoding.ASCII.GetBytes ( s ) ;
st = tc.GetStream( ) ;
st.Write ( buf, 0, s.Length ) ;
recvthread r = new recvthread ( st, text ) ;
Thread t = new Thread ( new ThreadStart ( r.getfile ) ) ;
t.IsBackground = true ;
t.Start( ) ;
}
In this handler we have obtained the file name and attached
a character to the string object to mark the end of the file
name. Why we need this would be clear in a short while. To
write the file name on stream we have first created an array
of bytes and copied the contents of the string object into
the array. We have then obtained the stream object by calling
the GetStream( ) method and written the filename to the stream
by calling the Write( ) method of the NetworkStream class.
The Write( ) method writes to the stream and advances the
current position within this stream by the number of bytes
written. Next, we have started a thread as we did for server.
This time we have passed the reference to the NetworkStream
object as well as reference to the TextBox object. Note that
this time we have passed two arguments to the constructor
of the recvthread class. The getfile( ) method would receive
the file contents sent by the server and display them in the
text box. Let us now see how the recvthread class is declared.
class recvthread
{
NetworkStream ns;
TextBox tb;
public recvthread(NetworkStream s, TextBox t)
{
ns = s;
tb = t;
}
public recvthread(NetworkStream s)
{
ns = s;
}
public void sendfile()
{
byte[] buffer = new byte[255];
ns.Read(buffer, 0, buffer.Length);
string str = Encoding.ASCII.GetString(buffer);
int i = str.IndexOf (*);
str = str.Substring(0,i);
string filestr = ;
try
{
FileInfo f = new FileInfo(str);
StreamReader sr = f.OpenText();
string temp;
do
{
temp = sr.ReadLine();
filestr += temp;
filestr += \r\n;
}while (temp != null);
byte[ ] buf = new byte [filestr.Length];
buf = Encoding.ASCII.GetBytes(filestr);
ns.Write(buf, 0, filestr.Length);
}
catch(Exception e)
{
MessageBox.Show ( e.ToString( ) ) ;
}
}
public void getfile()
{
byte[] buffer = new byte[512];
ns.Read(buffer, 0, buffer.Length);
string str = Encoding.ASCII.GetString(buffer);
tb.Text = str;
}
}
The class contains two data members that are initialised in
the constructor. The class has two constructors of which one-argument
constructor is called from the bserver_Click() handler, whereas,
the two-argument constructor is called from the bclient_Click()
handler.
In the sendfile() method, which would get called when the
server thread starts, we have called the
Read() method of the NetworkStream class. The Read() method
reads a sequence of bytes from the stream referred to by s
and advances the current position within the stream by the
number of bytes read. In our case, the Read() method would
read the file name written to the stream by the client. The
bytes read would get stored in the buffer array. We have encoded
the bytes read in the buffer array into a string using the
Encoding.ASCII.GetString() method. This method would copy
all the 255 characters to the string object. We must take
only that part of the string where the filename is stored.
For this we would use the end mark * that we have
concatenated to the file name in the bopen_Click() method.
In the next few statements, we have opened the file and read
its contents. Now the only job remaining is to write the contents
back to the client. We have done so by calling the Write()
method. The client also stands ready to read the file contents
in the getfile() method.
In the getfile() method we have merely called the Read( )
method, converted the byte stream into a string and displayed
it in the text box.
Lastly, add the following using statements at the beginning
of the program.
using System.Net.Sockets ;
using System.Text ;
using System.IO ;
using System.Threading ;
The following snapshots display file transfer application
at work.

 |
Yashavant
Kanetkar, one of the first Express Computer columnists,
is an established software expert, speaker and author
with several best-sellers to his credit, including titles
like “Let Us C” and the “Fundas” series. Contact him at
kanet@nagpur.dot.net.in |
|