Kamis, 07 Juni 2012

Aplikasi Chatting Server Client dengan Pemrograman Socket Java


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);
}
}

Perintahperintah 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
perintahperintah 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 JFramenya. 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 bagianbagian 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