PENGANTAR
Biasanya, server berjalan
pada komputer tertentu dan memiliki sebuah socket yang terikat pada nomor
port tertentu. Server hanya
menunggu, mendengarkan socket untuk seorang klien untuk membuat
permintaan sambungan.
Di sisi klien: klien
mengetahui nama host dari mesin server yang sedang berjalan dan nomor port di
mana server mendengarkan.
Untuk membuat permintaan sambungan, klien mencoba untuk bertemu
dengan server pada mesin
server dan port. Klien juga perlu mengidentifikasi dirinya ke server sehingga
mengikat ke nomor port
lokal yang akan digunakan selama hubungan ini. Hal ini biasanya diberikan oleh
sistem.
Jika semuanya berjalan
dengan baik, server menerima koneksi. Setelah diterima, server mendapatkan
soket baru terikat port
lokal yang sama dan juga memiliki titik akhir yang di atur ke alamat dan port
dari
klien. Diperlukan soket
baru sehingga dapat terus mendengarkan permintaan sambungan socket
sementara mengurus
kebutuhan klien yang terhubung.
Di sisi client, jika
koneksi diterima, socket berhasil dibuat dan klien dapat menggunakan soket
untuk
berkomunikasi dengan
server. Klien dan server dapat berkomunikasi dengan menulis atau membaca dari
soket
PENJELASAN
Berikut ini adalah source
code, penjelasan dan hasil eksekusi aplikasi ini.
server.java
Pada server, pertama
dilakukan pembukaan port 9999 dan menunggu koneksi.
try
{
serverSocket
= new ServerSocket(9999);
}
catch(IOException
e)
{
System.out.println("IO
"+e);
}
Kemudian dibuatlah objek
dari kelas cThread sehingga kelas tersebut dapat dijalankan dengan method
start().
while
(true)
{
try
{
clientSocket
= serverSocket.accept();
cThread
s = new cThread(clientSocket);
clients.add(s);
s.start();
}
catch
(IOException e)
{
System.out.println("IOaccept
"+e);
}
}
Jika koneksi sudah
terbentuk dari permintaan login, server akan memeriksa nickname karena harus
unik.
Jika nickname yang sudah
dipakai, server akan mengirim permintaan nickname yang baru.
Jika nickname tersedia ,
server akan mengirim daftarnya ke semua client. Selanjutnya, jika banyak client
yang terhubung dengan
server dan ada yang mengirim pesan umum, maka server akan meneruskannya
ke semua client. Sedangkan
jika client menerima pesan privat, maka server hanya akan meneruskannya
ke tujuannya.
Jika server menerima
perintah log out, maka dihapuslah nickname tesebut dari list dan mengirim
kembali up date list client
terbaru ke semua client. Server bekerja dengan Thread, sehingga dapat
menangani banyak client.
cThread.java
Pada program di bawah,
cThread membuat soket yang digunakan untuk berhubungan dengan server.
Input dari user akan dibaca
berupa standart output stream lalu meneruskan pesan tersebut ke server
dengan menuliskannya pada
soket. Server akan menampilkan input dari soket ke client. Program client
akan membaca dan
menampilkan pesan dari server.
Selanjutnya terdapat
perintah untuk mendapatkan output stream dari soket dan membuka PrintWriter
di dalamnya. Kemudian
dilakukan perintah untuk mendapatkan input stream dari soket dan membuka
BufferedReader di dalamnya. Untuk mengirim data melaluii soket ke
server, cThread cukup
menuliskannya pada PrintWriter.
Untuk mendapat respon dari server, cThread membacanya dari
BufferedReader.
try
{
out
= new PrintWriter(clientSocket.getOutputStream(),
true);
in
= new BufferedReader(new
InputStreamReader(clientSocket.getInputStream()));
}
catch
(Exception e)
{
System.out.println(e);
}
}
Perintah‐perintah selanjutnya merupakan perintah untuk merespon
tindakan user yang melakukan
login, log out, menulis
pesan public dan privat. Dimulai dengan kode di bawah ini yang melakukan
pengecekan akan adanya
pesan (msg) pada BufferedReader (i). Jika benar , lalu dicek juga apakah
pesan
yang diterima diawali
dengan ”Login”, jika ya, maka akan dipanggil method login().
while
(true)
{
String
msg = in.readLine();
System.out.println(msg);
if
(msg.startsWith("Login"))
{
login(msg);
}
Jika pesan yang diterima
adalah pesan log out maka koneksi dengan client akan diputus dengan perintah
close().
else
if (msg.equals("Logout")){
if
(connected) {
connected
= false;
int
k = server.clients.indexOf(this);
server.clients.remove(this);
sendList();
out.println("OK");
out.close();
in.close();
clientSocket.close();
return;
}
Jika pesan diawali dengan
post maka server akan mengirim ke pesan ke semua client dan jika diawali
dengan privatepost maka
pesan hanya akan dikirim ke client tujuan.
else
if (msg.startsWith("Post ")) {
for
(int i = 0; i < server.clients.size() ; i ++)
{
cThread
t = (cThread)server.clients.get(i);
if
(t.connected) {
t.send("Recieve
"+ nick+": "
+msg.substring(5,
msg.length()));
}
} }
else
if (msg.startsWith("PrivatePost ")) {
StringTokenizer
st = new
StringTokenizer(msg.substring(12,msg.length()),",
");
String
message = st.nextToken();
String
to = st.nextToken();
boolean
success = false;
for
(int i = 0; i < server.clients.size() ; i ++)
{
cThread
t = (cThread)server.clients.get(i);
if
(t.nick.equals(to))
{
t.send("PrivateRecieve
"+ nick+": " +
message);
success
= true;
break;
Kelas ini memiliki method
bernama login() yang digunakan untuk memeriksa nickname yang digunakan
client agar tetap unik
dengan perulangan berikut.
for
(int i = 0;i<server.clients.size();i++) {
if
(server.clients.get(i) != null) {
System.out.println(msg.substring(7,
msg.length()));
cThread
temp = (cThread)server.clients.get(i);
if
((temp.nick).equals(msg.substring(7, msg.length())))
{
exists
= true;
break;
Kelas ini juga memiliki
methode send() yang digunakan untuk mengirim list client yang terkoneksi.
for
(int i = 0; i < server.clients.size() ; i ++) {
cThread
t = (cThread)server.clients.get(i);
if
(t.connected) {
t.send(list);
}
Pada sisi client, ada 4
kelas yang dibentuk:
1. readFromServer.java –
membaca koneksi dengan server
2. client.java – kelas
untuk membuat GUI dari aplikasi chat ini dengan menggunakan JFrame milik
Netbeans
3. userInput.java – untuk
menuliskan pesan chatting
4. clientRunner.java –
untuk menjalankan GUI dari client.java, karena kelas ini bertugas untuk
membuat objek baru dari
kelas client tersebut.
readFromServer.java
Progam ini berisi pembacaan
client terhadap server. Di antaranya adalah, menerima pesan umum,
pesan privat, mengetahui
list terakhir client yang terhubung ke server, dan peringatan bahwa nickname
yang diinginkan sudah
dipakai sehingga harus menggunakan nickname lain. Hampir sama dengan
perintah‐perintah pada cThread.java., kelas ini juga
menampilkan list client, pesan yang diterima baik
yang public maupun yang
privat dengan perintah di bawah ini.
System.out.print("List
updated: New names: ");
for
(int i = 0; i < client.list.size();i++)
{
System.out.print(client.list.get(i)
+ " ");
}
System.out.println();
}
else
if (s.startsWith("Recieve"))
{
client.mainText.setText(client.mainText.getText()
+
"\n"
+ s.substring(8,s.length()));
client.mainText.setCaretPosition(client.mainText.getText().length());
}
else
if (s.startsWith("PrivateRecieve"))
{
client.mainText.setText(client.mainText.getText()
+
"\n"
+ "Privat Messages: " + s.substring(14,s.length()));
client.mainText.setCaretPosition(client.mainText.getText().length());
}
Untuk menjalankan client,
langkah pertama yang harus dilakukan adalah menjalankan servernya dulu,
setelah itu run
clientRunner.java untuk membuat objek baru. Jika ingin membuka lebih dari 1
client, run
lagi clientRunner.java
untuk membuat objek lagi.
clientRunner.java
Kelas ini hanya bertugas
untuk membuat objek baru dari kelas client.java. Jika ketika ingin mencoba
memunculkan lebih dari 1
client, kita tinggal mengompile kelas ini. Untuk menjalankan GUI dari program
chat ini, kita harus
membuat objek terlebih dahulu, otomatis kelas inilah yang di run terlebih
dahulu
setelah menjalankan server.
userInput.java
Kelas ini merupakan turunan
dari kelas Thread. Seperti tugas yang lalu mengenai fungsi run, dalam kelas
ini dideklarasikan method
bernama run(). Tujuan dari method ini adalah mengatur input dan output text
dari ke server. Dalam
method run() ini berisi pemanggilan fungsi read() dan send(), 2 method ini
dideklarasikan pada kelas
client.java. Tugas dari method send() adalah mengeluarkan input message dari
client.
client.java
Bisa dibilang kelas ini
merupakan program dari client yang utama. Pada kelas ini dibuat GUI sebagai
interaksi untuk melakukan
chatting dengan antar client. GUI dari program ini dibuat dengan bantuan
Netbeans dengan JFrame‐nya. Jadi kebanyakan dari tampilan source code
merupakan hasil dari
generate Java Swing
tersebut. Sedangkan logicnya hanya berada pada aksi button, input text dan
menu-menu terkait. Yang akan dibahas hanya bagian‐bagian
pentingnya saja, berikut penjelasannya
private
void nickListMouseClicked(java.awt.event.MouseEvent evt)
{
if
(connected && (!nickList.getSelectedValue().equals(nick)))
{
String
msg = JOptionPane.showInputDialog(null, "server:");
if
(msg != null)
{
send("PrivatePost"+msg+","+nickList.getSelectedValue());
}
System.out.println(nickList.getSelectedValue());
}
}
Perintah diatas merupakan
perintah disaat kita melakukan private message kepada client tertentu.
Ketika event bernilai true,
maka akan muncul dialog yang bertanya server mana yang dituju. Jika benar,
akan tertulis Private Post
dan pesannya pada server.
private
void jMenuItem1ActionPerformed2(java.awt.event.ActionEvent evt)
{
send("Logout");
client.logout
= true;
System.exit(0);
}
Perintah diatas untuk
action ketika menu Disconnect diklik, akan muncul tulisan Logout pada server
dan
system client langsung
berhenti.
private
void jMenuItem1ActionPerformed3(java.awt.event.ActionEvent evt)
{
String
s;
s
= "Login and Connect. Connect to localhost then input your
username\n";
JOptionPane.showMessageDialog(
this, s,"Usage",
JOptionPane.INFORMATION_MESSAGE
);
}
Perintah diatas ketika menu
Help lalu Usage diklik. Muncul popup message yang berisi seperti string
yang ada dalam variable s
diatas.
static
String server;
private
void jMenuItem1ActionPerformed(java.awt.event.ActionEvent evt)
{
setTitle("Connecting
...");
logout
= false;
sinput
= new readFromServer(this);
uinput
= new userInput();
cSocket
= null;
out
= null;
in
= null;
boolean
error;
error
= false;
server
= JOptionPane.showInputDialog("Server: ", "localhost");
try
{
cSocket
= new Socket(server,9999);
out
= new PrintWriter(cSocket.getOutputStream(), true);
in
= new BufferedReader(new
InputStreamReader(cSocket.getInputStream()));
uinput.start();
sinput.start();
}
catch(UnknownHostException
e)
{
JOptionPane.showMessageDialog(
this, "No server is
found","ERROR",
JOptionPane.ERROR_MESSAGE );
System.out.println("Host
Error" + e);
setTitle("Simple
Java Chat - Cannot Connect Please Try
another
server");
error
= true;
}
catch
(IOException e)
{
System.out.println("IOException"
+ e);
}
if
(!error)
{
nick
= null;
nick
= JOptionPane.showInputDialog(null, "NickName: ");
while(nick.contains(";"))
{
nick
= JOptionPane.showInputDialog(null,"Input
Nickname\";\".Cannot
be null.");
}
send("Login:
"+nick);
if
(nick != null)
{
jMenuItem1.setEnabled(false);
jMenuItem2.setEnabled(true);
}
}
}
Sedangkan perintah diatas
mengatur client ketika akan connect. Dimulai ketika menu Connect pada
menubar Login di klik.
Awalnya client harus membaca dulu, apakah server sudah jalan atau belum, jika
belum tidak akan bisa
tersambung. Jika sudah berjalan servernya, akan muncul popup yang menanyakan
alamat server, dalam hal
ini kita isi dengan localhost. Lalu akan ditanyakan nickname untuk login. Saat
kita mencoba tersambung
dengan server, cSocket akan membuat objek baru yang mengakses port 9999.
Namun, ketika server tidak
ditemukan, akan muncul popup message yang meminta kita untuk
menuliskan alamat server
yang tepat.
void
sendInput()
{
if
(!connected)
{
JOptionPane.showMessageDialog(
this, "Not connected! Actions -
Connect","Error",
JOptionPane.ERROR_MESSAGE );
inputText.setText("");
}
else
if(inputText.getText().equals("") ||
inputText.getText().equals("\n")
|| inputText.getText()== null )
{
inputText.setText("");
}
else
{
send("Post
" + replace(inputText.getText(),"\n"," "));
inputText.setText("");
}
}
Fungsi diatas merupakan
method sendInput() yang merupakan method untuk membaca input yang
diinput oleh client. Method
ini digunakan untuk memasukkan text ke server, lalu server melempar string
tersebut ke client yang
dikehendaki.
PasswordDemo,java
Pada kelas ini dilakukan
request password kepada client. Password yang dimasukkan client akan dicek
benar atau tidak dengan
method isPasswordCorrect. Jika password salah, maka client tidak dapat
melakukan koneksi ke
server.
private
static boolean isPasswordCorrect(char[] input) {
boolean
isCorrect = true;
char[]
correctPassword = { 't', 'e', 's', 't', 'i', 'n', 'g' };
if
(input.length != correctPassword.length) {
isCorrect
= false;
}
else {
isCorrect
= Arrays.equals (input, correctPassword);
}
//Zero
out the password.
Arrays.fill(correctPassword,'0');
return
isCorrect;
Output :
Request Password
Sukses memasukkan password
Pesan bila password yang dimasukkan salah
Client login
Input nickname
Test chatting
server
Private Message oleh Ega ke Ninan
Private Message yang diterima Ninan tidak diterima Fulan
Tidak ada komentar:
Posting Komentar