الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

مشروع عمل (Client/Server Chat)

مغلق
بدأه xpx في 17 ديسمبر 2006 · 2 رد · 2,660 مشاهدة · في JavaSE
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

We will use the previous tutorial to write a Chat application. This application allow a client to communicate with all the other clients connected to the server.

The communication is done by implementing a specific protocol between the server and clients. This is used to decode data received and encode datas to send.

Threads are also used for doing action automatically like reading input datas

Tutorial

The basis of client/server was seen in Tutorial 1.

Talking with multiple clients

In the previous tutorial, a client can send datas only to the server. In a chat application, the client could send datas to anyone connected.

To send datas from a client to another, the datas can goes directly from one client to the other.

Another way is to send datas to the chat server and inform him that datas are for a particular client. We will use the second way for this chat tutorial

Tutorial02-MessageTransmission.png

Transmission of a message

The advantage of this is that the client have a single connection (to the server) and can talk with multiple clients. Moreover, the server don't transmit the IP of a client to another one (security).

Implementation on the Server

All clients have to connect themself to the server.

The server should listen for client connection. For this, acceptConnection is called in loop in a thread (this method blocks until a connection is made).

Accept client connections


public void run()
{
while(user.isConnected())
{
ChatServerLink client = null;
//acceptConnection blocks until a connection is made
if((client = user.acceptConnection() ) != null)
{
//A new client is connected
...
}
}
}
};
acceptClientsThread = new Thread() {

ChatServerLink class extends ServerLink used in previous tutorial for storing client pseudo, client authentification and a thread used to listen for datas received (this thread will be used later in this tutorial).

ChatServerLink


{
/** Pseudo of the client connected to the Link */
private String pseudo = null;
/** Client is authentified ? */
private boolean authentified = false;

/** Thread that listen for datas received */
protected Thread listener = null;

... //Constructor, getters & setters
}
public class ChatServerLink extends ServerLink

Communication language

To interpret data flow, datas should be encoded in a language understandable by the server and the client.

By using the same language for the client and the server, the sender is sure that his datas sended are well processed by the receiver. For example, a client can send an instruction (to the server) to transmit some datas to another.

Definition of the language

Before implementing the language used by the chat application, we have to know which instructions will be transmitted from a client to another or towards the server.

This chat application will works like this :

A client must authentify him, to the server, by sending his pseudo. Pseudo is unique.

A client not identified can't use the chat service until he his authentified.

The server send the list of clients authentified to each client authentified.

A client can send a text message to any client authentified.

The server can disconnect any client he wants and send any information to any clients he wants.

Encoding/decoding

We have to encode original instruction to a succession of bytes/characters. Datas encoded could be decoded to extract the original instruction.

Datas will be encoded using tags :

<TAG>value</TAG>

TAG is a reserved word associated to an instruction.

value is the value of the instruction.

Tag used to implement the language are (in ProtocolEnums):

REQUEST : request a pseudo or a disconnection.

MESSAGE : text message from a client to another

PSEUDO : authentification of a client to the server.

PSEUDO_LIST : contains pseudo list of client authentified

INFO : Information message from the server (will be opened in a dialog box).

To send a message from a client (Pseudo1) to another (Pseudo2), the client will encode his message like this :

<MESSAGE><FROM>Pseudo1</FROM><TO>Pseudo2</TO><BODY>Text</BODY></MESSAGE>

When the server will receive this message, by parsing the datas, he will fing the tag MESSAGE. Value of this tag is <FROM>Pseudo1</FROM><TO>Pseudo2</TO><BODY>Text</BODY>. He already know which client is the sender (because he receive the datas from him), by parsing this value he will find the addressee and the text to send him.

Encoding and decoding are done in Encoder/Decoder classes.

Implementation

First thing is to listen if some datas are received. For this, we will use a thread that check in loop if some datas can be readed.

When some datas can be readed, with process them in processInput by implementing the Protocol interface.

Receiving thread


listener = new Thread() {
public void run()
{
boolean end = false;
while(!end)
{
try
{
//Call getProtocol.processInput(...) if some datas are received
user.checkInput();
}
catch(IOException e)
{
end = true;
}

try
{
Thread.sleep(20);
}
catch(InterruptedException e){}
}
user.disconnect();
}
};
listener.start();
//Listen for datas received

Now, we have to implement our language with the Protocol interface and attach it to our connection with connection.setProtocol(protocol)

Protocol


{
public void processInput(InputStream datas);
}

user.setProtocol(new Protocol(
public void processInput(InputStream in)
{
//Process input by implementing the protocol here
...
}
));
public interface Protocol

The implementation is different for the server and the client. For example, the server ask for authentification and the client answer the request.

Here is how datas are processed by a client (in Client).

First, he read the datas into a String. Then, he parse the datas as a vector containing tags and their corresponding values. Finally, depending on tag received, we do what should be done.

Client side


{
//Read inputs
String datas = null;
try
{
while(in.available() > 0)
datas += new String(user.readInput());
}
catch(IOException e)
{
return;
}
datas = datas.trim();

//Decode datas
Vector<TagValue> queries = decodeTag(datas); //Using Decoder class (static import)

//Process inputs
for(TagValue tagValue : queries)
{
switch(tagValue.tag)
{
case REQUEST:
if(Request.valueOf(tagValue.value) == Request.PSEUDO)
{
//Server request authentification
...
}
else if(Request.valueOf(tagValue.value) == Request.DISCONNECTION)
{
//Server request disconnection
...
}
break;
case MESSAGE:
//A new message
...
break;
case PSEUDO_LIST:
//List of pseudo
...
break;
case INFO:
//Message from the server
...
break;
}
}
}
[code]

Now, how datas are processed by the Server (in Server).
The server manage authorizations. He blocks datas from client not authentified.

Server side
public void processInput(InputStream in)

public void processInput(InputStream in)

{

//Read inputs

String datas = null;

try

{

while(in.available() > 0)

datas += new String(client.readInput());

}

catch(IOException e)

{

return;

}

datas = datas.trim();

//Decode datas

Vector<TagValue> queries = decodeTag(datas); //Using Decoder class (static import)

//Process inputs

for(TagValue tagValue : queries)

{

if(client.isAuthentified())

{

switch(tagValue.tag)

{

case REQUEST:

if(Request.valueOf(tagValue.value) == Request.DISCONNECTION)

{

//Disconnection of the client

...

}

break;

case MESSAGE:

//Message to transmit to a client

...

break;

}

}

else

{

if(tag.tag == Tag.PSEUDO)

{

//The client send his pseudo

...

}

else

{

//Block it ! Client is not authentified

...

}

}

}

}

Classes used

I've just explain interesting part ie new 'Network' part of this tutorial.

A lot of code is for the GUI (not explained here).

In package Network.Chat :

IntroFrame : first frame, display author informations and ask if you are the server or a client.

SettingsFrame : second frame, ask informations like your pseudo, IP and communication port.

IpPanel : used by SettingsFrame to enter an IP address.

ChatFrame : GUI.

Server : code for the server.

Client : code for the client.

In package Network.Chat.Protocol :

Encoder : Encode datas

Decoder : Decode datas.

ProtocolEnums : contains tag of the communication language.

ChatServerLink : extends ServerLink to store user properties.

Hope that you like this tutorial !

Advanced Part

Communication language

Instead of defining a communication language like we have doing here, you can use RMI (Remote Method Invocation) for doing the same job.

RMI allows you to invokes methods on an object running in another JVM (Java Virtual Machine). That is to say, for examples, two differents Java applications.

Server side

The chat server runs here in a GUI. Generally, the server have no GUI an runs without human intervention.

Clients register themself to the chat server and have a pseudo/login. They log themself by sending their pseudo/login to the server.

Sending files

In this tutorial, like the previous, we have only seen how to send text (characters).

But, we can send files, pictures ...

This will be done in Tutorial 3, a basic HTTP server.

Screen shots

I've run a server and 2 clients (you can connect all clients you wants). These 3 applications runs independently.

I've runs them in the same computer for these screen shots, but they can be executed under differents computers and differents OS.

Here are what the two clients sees :

Tutorial02_ScreenShotClients.png

Tutorial02_ScreenShotClients.png

Clients applications

Here is the server application :

Tutorial02_ScreenShotServer.png

وشكراً لكم ارجؤ انكم استمتعو في هذا شرح وللمزيد قريباً

تم تعديل هذه المشاركة بواسطة xpx في 17 ديسمبر 2006 في 20:00

#2

لو كان الشرح معرب لكان أفضل ، لزيادة معدل الفائدة

#3

اخي كريم هذا شرح من موقع اجنبي وشكراً

http://jerome.jouvie.free.fr/

رابط هذا اهو شرح تلقاء فيه دروس وشكراً

هذا الموضوع مغلق.

مواضيع مشابهة