|
Chapter 4: System Implementation
|
<< Page
1
2
3
4
5
6
>> |
4.1.1.1.
File Transmission
Once the file has been compressed by the
sender’s application, the system is now ready
for transmission.
4.1.1.1.1.
Sending File
On the file sender’s application and after the
file has been compressed, the application
initiates a new thread for file transmission.
The new thread is responsible for handling file
transmission to the receiver’s application. To
prevent the network from overloading, the
sender’s application transmits the file as
streams (arrays) of bytes of size 2048.
|
Socket socket = client.get_socket();
//get the communication socket
File zipFile = new File(file +
".zip"); //get
hold of the new compressed file
FileInputStream fi = new
FileInputStream(zipFile);
//an inputstream to read from file
BufferedInputStream origin = new
BufferedInputStream(fi, 2048);
//create an object output stream for
communication with the other party
ObjectOutputStream oos = new
ObjectOutputStream(socket.getOutputStream());
byte data[] = new
byte[2048];
//get filename and size and send it
to client
setDebugLabel("Sending file detials...");
int size = origin.available();
oos.writeObject(new Message(file +
".zip", size,
false));
//start sending file
setDebugLabel("Transferring...");
int progress = 0;
int
count;
while((count = origin.read(data, 0 ,
2048)) != -1){
oos.write(data, 0,
count);
//transfer read
bytes
oos.writeObject(new
Message("ISCFILEEXCHANGE-CONT"));
progress = progress +
count;
//calculate progress
bar.updateProgress(progress
/ size * 100); //update
progress bar
setDebugLabel("Sending
file... " + (size -
progress) + " K remaining.");
}//close while
oos.writeObject(new
Message("ISCFILEEXCHANGE-DISCONT"));
//free system resources
fi.close();
origin.close();
setDebugLabel("File was successfully
transferred.");
zipFile.delete();
//deleted
compressed file |
Figure 4.37: Sending file.
Figure 4.38: File transfer session – sending
file.
Once the new compressed file has been
transferred, the application deletes it.
4.1.1.1.2.
Receiving File
As mentioned earlier, once the receiver’s
application launches the file transfer session,
the application attempts to create a
“ServerSocket” and listens to the port waiting
for an incoming connection from the sender’s
application. As soon as the connection has been
established, a new thread is started to receive
the file.
|
//create an object input stream to
receive file from other party
ObjectInputStream i = new
ObjectInputStream(socket.getInputStream());
//get file name and size from other
party
String file;
Message o = (Message)i.readObject();
file = o.msg;
int size = o.integerMsg;
//store the file in the “Downloads”
folder
FileOutputStream dest = new
FileOutputStream("Downloads/" +
file);
BufferedOutputStream out = new
BufferedOutputStream(dest); //a
buffer to write to file
byte data[] = new byte[2048];
int
count;
int progress =
0;
while((count = i.read(data, 0 ,
2048)) != -1){
o = (Message)i.readObject();
//get array of bytes
out.write(data, 0,
count);
//save read bytes
to disk
progress = progress +
count;
//calculate progress
bar.updateProgress(progress
/ size * 100); //update progress
bar
setDebugLabel("Recieving
file... " + (size -
progress) + " K remaining.");
if ( !o.msg.equals("ISCFILEEXCHANGE-CONT")
) break;
}//close while
setDebugLabel("File was successfully
tranferred.");
out.close();
//free system resources
closeConnection();
//free
system resources |
Figure 4.39: Receiving file.
Figure 4.40: File transfer session – receiving
file.
4.1.2.
ISC File Transfer Commands
The File Transfer Subsystem defines two ISC
commands that are used during file transmission.
Since, the sender’s application breaks down the
file that is intended to be transferred, it is
essential for the application to alert the
receiver’s application whether or not there are
more bytes to transmit. On the other hand, once
the receiver’s application receives a stream of
bytes, it halts waiting for an ISC command that
indicates whether or not to continue listing
through the port or to close the communication
channel.
|
ISC File Transfer Command |
Description |
|
·
"ISCFILEEXCHANGE-CONT" |
Indicates that the sender’s
application has more to send. Hence,
the receiver’s application should
wait. |
|
·
"ISCFILEEXCHANGE-DISCONT" |
Indicates that the sender’s
application has nothing more to
send, therefore, communication
channel will be closed. |
4.2.
ISC Administrative Application
The ISC Administrative Application is the
application that is used by the system
administrators to manage clients’ accounts,
including adding new accounts and deleting
existing accounts. This application is much
simpler than the other ISC applications, as it
only provides a user-friendly interface with two
primary functional buttons: “ADD USER” and
“DELETE USER”. Note that a full coding of
the administrative application is provided in
Appendix C.
Figure 4.41: ISC Administrative Application.
4.2.1.
Key to Figure 4.41
(1)
Screen-name text field
The screen-name text field is where system
administrators are required to enter the new
client screen-name.
(2)
Passcode text field
The passcode text field is where system
administrators are required to enter the new
client passcode. Once the “Enter” key is
hit, the application attempts to register the
client.
(3)
Add user button
This is once of the primary functional
components of the application. Once the new
client’s screen-name and passcode has been
entered in the screen-name text field and the
passcode text field, the system administrator is
required to either click on this button or just
hit the “Enter” key in the passcode field
in order to register client.
The process of registering clients is carried
out by various methods, which are: “addUser()”,
“checkTextAreas()”, and “registerUser()”.
However, the primary method which adds the new
client to the database is the “registerUser()”
method using “RandomAccessFile”.
|
do{
database.seek(recordOffset);
//recordOffset is 0; go to the
beginning of the database
recordCount =
database.readInt(); //read id
number
screenName =
database.readUTF(); //read
screen name
passcode = database.readUTF();
//read passcode
if (
screenName.equals(user.get_screen_name())
){ //does the new screen
exist
…
break;
//display an error message and stop
the process
}//close if
if ( recordCount == -1
){ //is it
the last record in the database?
database.seek(recordOffset);
database.writeInt(count);
//write id
database.writeUTF(user.get_screen_name());
//write screen name
database.writeUTF(user.get_passcode());
//write passcode
//add a terminator;
the terminator is to determine the
end of the file
…
}//close if
else
recordOffset =
database.getFilePointer();
//go to the next record
count++;
}while(recordCount != -1); |
Figure 4.42: Client registration.
(4)
Registered users list
This component is used to list the clients who
are already registered. Once the application is
loaded, it attempts to read from the database to
list registered users. However, the list is
updated once a new user is added or an existing
user is deleted.
(5)
Delete user button
If the administrator wishes to delete an
existing user from the ISC database, the user
should be selected from the “Registered users
list” then the “DELETE USER” button
should be clicked.
|
//close database
database.close();
//delete current database
File db = new File("ISCDatabase.db");
db.delete();
//create a new database
database = new
RandomAccessFile("ISCDatabase.db", "rw");
int index = 0;
Enumeration e = users.elements();
do{ //add user as long as it is
not the one to be deleted
if ( !((User)users.elementAt(index)).get_screen_name().equals(user)
){
if ( index == 0
) //is it
the first user to add?
registerUser((User)users.elementAt(index),
0);
else
registerUser((User)users.elementAt(index));
}//close if
index++;
e.nextElement();
}while(e.hasMoreElements()); |
Figure 4.43: Delete an existing user.
(6)
Exit button
The exit button is to enable the administrator
to exit the application after the computer
resources is freed.
(7)
Tip box
The tip box is to provide more interactivity
with the administrator. As some operations that
may be performed by the administrator are not
allowed, the tip box is used to alert the
administrator with invalid operations, e.g. the
administrator has clicked on the “ADD USER”
button without enter the new client’s
screen-name and passcode. In addition, the tip
box is also used to display messages stating the
result of the administrator’s operations
results, e.g. if the administrator’s operation
of adding a new client is successful, a message
is displayed in the tip box stating such a
result.
4.3.
Problems Encountered
In this section, the problems that were
encountered during the implementation phase of
the ISC system are listed below.
4.3.1.
ISC Voice Conferencing Subsystem
As mentioned earlier in the system design
chapter, the main objective of the ISC Voice
Conferencing Subsystem is to enable online ISC
clients to establish real-time voice
conferencing sessions amongst each other. The
intended subsystem was to be implemented based
on the client/server model and the Real-Time
Transfer Protocol (RTP) using Java Media
Framework (JMF).
However, prior the implementation phase of the
intended system, an intensive research was
performed to learn the multimedia features that
are provided by Java Media Framework and its
ability to support real-time applications.
Furthermore, the research also covered the RTP
protocol and the ability to integrate it along
with the JMF. Therefore, the research phase was
time-consuming.
As JMF is a recent release of Sun Microsystems,
it is not supported by JDK versions 1.2 nor
version 1.4 that can be used by both of the
programming tools, JBuilder and Symantec Visual
Café 3 that have been used for the development
of the other ISC subsystems. However, the
problem encountered can be overcome by adding
the JMF libraries to the current JDK.
The task of adding the JMF libraries to the JDK
used by JBuilder that was used to develop the
ISC Server module was successful. However, when
JMF libraries were added to the JDK used by
Visual Café that was used to develop the ISC
Client module, vital Java Virtual Machine errors
occurred. Furthermore, the successor version of
Visual Café that supports JMF was unaffordable.
4.3.1.1.
Attempts to shit to other programming tools
Since the ISC Voice Conferencing Subsystem
implementation is concerned with the client
application, an alternative programming tool
that supports JFM should be adopted instead of
Visual Café in order to implement the subsystem.
The following programming tools had been
installed in order to test their ability
integrate with the JMF libraries.
4.3.1.1.1.
Microsoft J++
Microsoft J++ provides a Visual Basic like
style. On the other hand, as the ISC Client
Application subsystems were developed using some
of the Symantec Visual Café libraries, the
attempt of shifting to Microsoft J++ required
the task of adding these libraries to the JVM
that is used by J++. However, although the task
of adding Symantec libraries was successfully
overwhelmed, the already-developed client
application did not function properly.
Furthermore, adding the JMF libraries lead to
too many errors that prevented the application
from loading.
4.3.1.1.2.
Forte for Java
Since the Forte Java, by Sun Microsystems, runs
using the latest JDK (Java 2 platform), it
supports Java Media Framework. However, as
mentioned earlier, the client application
subsystem has already been developed using some
of the Symantec libraries. Therefore, it was
essential to perform the task of adding these
libraries to the JVM over again in order to be
able to execute the application. After
installing Symantec libraries to the JVM, the
application could be loaded successfully.
However, running the application with Forte has
lead to a huge change in the application’s
interface. In addition, the process of the
running the application was extremely slow and
frequently lead the computer to crash. Lastly,
the Forte for Java does not provide any kind of
visual facilities.
Consequently, this left me to try my last hope
which is JBuilder.
4.3.1.1.3.
JBuilder
Since JBuilder is the programming tool that has
been used to develop the ISC Server module, I
have become familiar with its environment.
However, in order to test its ability to
integrate JMF libraries and run the client
application properly, it was essential to
install both of Symantec and JMF libraries to
the JVM. Fortunately, the process of installing
these libraries was successful. Nevertheless,
running the application on JBuilder has also
made a huge change in the application’s
interface. In addition, it caused the
already-developed ISC subsystems not to function
properly.
These unsuccessful attempts consumed so much of
the time that was set for the implementation
phase. Therefore, it was decided to simplify the
functionality of the Voice Conferencing
Subsystem in order to be able to implement the
system as a separate application using JBuilder
within the deadline.
4.3.2.
New Design
The new design of the ISC Voice Conferencing
Subsystem has forced the system to use TCP/IP
connection instead of the Real-Time Transfer
Protocol. Therefore, the new system does not
provide a real-time service; the new system
enables clients to establish voice message
exchange sessions.
4.3.2.1.
Connection setup process
As proposed for the older version of the system
design, prior launching the system, a connection
setup process must be performed in order to
establish a one-to-one TCP/IP communication
channel between two parties of the session. This
process is performed in the same manner as the
older version (please see the system design
chapter.)
4.3.2.2.
Voice message exchange
Once a communication channel has been
established, the two parties involved within a
session may transmit voice messages amongst each
other. The ability of transmitting voice
messages is grated to clients through a priority
mechanism. In other words, parties involved
within a session take turns in transmitting
their voice messages.
Consider the following example where “A”
is the voice session request sender and “B”
is the voice session request receiver.
Once the session is launched, “A” is
given the priority to transmit his/her message
to “B”, as a message is displayed for “A”
stating if he/she wishes to start; hence, one of
the following may occur:
þ
“A” reacts positively:
25 seconds of time is given for “A” to
record his/her message then the message is
transmitted over to “B”. Consequently,
after the transmitted message is received and
played by “B”, the latter is given the
priority to transmit his/her message.
ý
“A” reacts negatively:
an ISC command is issued and transmitted over to
“B” granting him/her the ability to
transmit a message to “A”.
This process is carried out in an endless loop
until an ISC “end-session” command is issued by
one the parties, which leads to the termination
of the session. Therefore, such a mechanism
gives clients equal opportunities to transmit
their voice messages.
4.3.3.
System Implementation
The proposed system was implemented
successfully. In this section, the light is
projected onto the primary segments of the
system. Note that a full coding of the
system is provided in Appendix D.
4.3.3.1.
Capture Voice Class
The CaptureVoice
class is used to enable clients to record their
message prior transmission. However, clients’
messages are of a maximum duration of 25 seconds
in order to limit the size of the recorded
message, and consequently, to provide an
efficient service for clients. In addition,
clients’ messages are recorded in the format of
WAV files due to its spread use and
compatibility.
|
//create a DataSource to read from
device (microphone)
DataSource dataSource =
Manager.createDataSource(audioCDI.getLocator());
audioPro =
Manager.createProcessor(dataSource);
//create a Processor for the
dataSource
audioPro.configure();
Thread.sleep(1000); //block
until configured
audioPro.setContentDescriptor(new
FileTypeDescriptor(FileTypeDescriptor.WAVE));
audioPro.realize();
Thread.sleep(10000); //block
until realized
DataSource source = null;
…
// get the output datasource of the
processor and exit if it fails
File waveFile = new File("Temp/temp.wav");
//create a new WAV file for message
recording
MediaLocator dest = new
MediaLocator("file:///" +
waveFile.getCanonicalPath());
DataSink d =
Manager.createDataSink(source, dest);
d.open();
StreamWriterControl swc = (StreamWriterControl)
audioPro.getControl("javax.media.control.StreamWriterControl");
//set limit of file size to 5MB
if (swc != null)
swc.setStreamSizeLimit(5000000);
d.start();
playerWindow = new
PlayerWindow(audioPro); |
Figure 4.44: Recording from a device.
Figure 4.45: Recording from a capture device.
4.3.3.2.
Capture Device Dialog Class
This class
enables clients to select the device their wish
to capture from as it list all available
devices. Once a client selects a device, it will
be used for the next capture request.
|
//get all the capture devices
devices =
CaptureDeviceManager.getDeviceList (
null );
CaptureDeviceInfo cdi;
if (devices!=null && devices.size()>0)
{ //end if devices != null &&
devices.size>0
int deviceCount =
devices.size(); //get
number of available devices
audioDevices = new
Vector(); //a Vector
that is used to store devices
information
Format[]
formats;
//create an array of Format
//loop through available
devices and register them for the
user to choose from
for ( int i = 0; i <
deviceCount; i++ ) {
cdi = (CaptureDeviceInfo)
devices.elementAt ( i );
formats =
cdi.getFormats();
for ( int j=0; j<formats.length;
j++ ) {
if (
formats[j] instanceof AudioFormat )
{
audioDevices.addElement(cdi);
break;
}//close
if
}//close for
}//close for
//populate the choices for
audio
for (int i=0; i<audioDevices.size();
i++) {
cdi = (CaptureDeviceInfo)
audioDevices.elementAt(i);
audioDeviceCombo.addItem(cdi.getName());
}//close for
displayAudioFormats();
}//close if
|
Figure 4.46: Searching for available capture
devices.
Figure 4.47: Selecting a capture device.
4.3.3.3.
Play Class
Finally, the
Play class is used to play audio files that may
be selected; hence, it acts as a media player
that provides clients the ability to play their
own audio file.
|
//display a file dialog for the
client to select the file he/she
wishes to play
FileDialog fd = new FileDialog(this,
"Select File", FileDialog.LOAD);
fd.show();
String filename = fd.getDirectory()
+ fd.getFile();
//initiate a player for the chosen
file to play
audioPlayer =
Manager.createPlayer(new
MediaLocator("file:///" +
filename));
audioPlayer.realize();
//realize Player
audioPlayer.addControllerListener(this);
//add controler
playerWindow = new
PlayerWindow(audioPlayer);
//create a PlayerWindow
audioPlayer.start();
//start
playing the audio file |
Figure 4.48: Playing an audio file.
Figure 4.49: Playing audio files.
In addition, the setup process was also
implemented successfully.
<< Page
1
2
3
4
5
6
>> |