Politeknik Negeri Sriwijaya
Niki Astri | Teknik Komputer
APLIKASI CHATTING MULTICLIENT BERBASIS GRAFIS DENGAN JAVA
Chatting menurut Bahasa Indonesia artinya mengobrol atau bercakap-cakap. Chatting
memungkinkan kita dapat mengobrol dengan teman, keluarga, saudara atau mungkin mencari
teman baru yang belum kita kenal. Chatting memungkinkan kita untuk selalu bisa
berkomunikasi walaupun kita tidak berada bersamanya di suatu tempat. Aplikasi chatting
merupakan suatu aplikasi yang memungkinkan pengguna (client) berkomunikasi teks secara
langsung (Real Time) dengan pengguna lain dengan menggunakan media yang ada.
Java merupakan suatu bahasa pemograman yang multi platform dan multi device. Java
juga merupakan bahasa pemograman yang berorientasi objek dan program java tersusun dari
bagian yang disebut kelas. Kelas terdiri atas metode-metode yang melakukan pekerjaan dan
mengembalikan informasi setelah melakukan tugasnya. Beberapa keunggulan java yaitu java
merupakan bahasa yang sederhana. Java dirancang agar mudah dipelajari dan digunakan secara
efektif. Java tidak menyediakan fitur-fitur yang rumit.
Pada bagian kali ini saya akan mencoba untuk membuat suatu aplikasi chatting multiclient
sederhana dengan menggunakan tampilan grafis berbasis bahasa pemograman java. Dimana
nanti masing-masing client yang terhubung ke jaringan dapat langsung bercakap-cakap secara
langsung.
Pertama yang harus dilakukan kita terlebih dahulu melakukan setting alamat IP pada
masing-masing client. Pada percobaan ini kita akan menggunakan 1 server dan 1 client. Adapun
alamat IP nya adalah sebagai berikut :
a. Server
Ip address : 10.10.10.1
Netmask : 255.0.0.0
b. Client
Ip address : 10.10.10.2
Netmask : 255.0.0.0
Politeknik Negeri Sriwijaya
Niki Astri | Teknik Komputer
Setelah melakukan konfigurasi IP pada masing-masingi komputer kemudian kita juga
harus memastikan bahwa firewall pada masing-masing komputer harus diaktifkan karena
pada beberapa kasus program ini tidak dapat saling terkoneksi akibat firewall yang aktif pada
sistem operasinya.
Lalu install Textpad versi 7 dan jdk versi 7 pada masing-masing komputer. Kemudian
langkah selanjutnya kita mengetikan listing program java untuk aplikasi chatting ini dengan
menggunakan TextPad. Programnya terbagi menjadi dua bagian yaitu bagian server dan client.
Adapun listing programnya adalah sebagai berikut.
1. ChatServer.java
import java.io.*;
import java.net.*;
import java.util.*;
public class ChatServer {
private static int uniqueId;
private ArrayList<ChatServer.ClientThread> clients;
private int port;
private boolean keepGoing;
public ChatServer() {
this.port = 9999;
clients = new ArrayList();
}
public void start() {
keepGoing = true;
try {
ServerSocket serverSocket = new ServerSocket(port);
while (keepGoing) {
System.out.println("ChatServer waiting for Clients on port "
+ port + ".");
Politeknik Negeri Sriwijaya
Niki Astri | Teknik Komputer
Socket socket = serverSocket.accept();
if (!keepGoing) {
break;
}
ChatServer.ClientThread t = new ChatServer.ClientThread(socket);
clients.add(t);
t.start();
send("login~" + t.username + "~" + t.username + " sedang
login...~Server~\n");
}
try {
serverSocket.close();
for (int i = 0; i < clients.size(); ++i) {
ChatServer.ClientThread tc = clients.get(i);
try {
tc.sInput.close();
tc.sOutput.close();
tc.socket.close();
} catch (IOException ioE) {
}
}
} catch (Exception e) {
System.out.println("Exception closing the server and clients: " + e);
}
} catch (IOException e) {
String msg = "Exception on new ServerSocket: " + e + "\n";
System.out.println(msg);
}
}
private synchronized void send(String message) {
for (int i = clients.size(); --i >= 0;) {
ChatServer.ClientThread ct = clients.get(i);
if (!ct.writeMsg(message)) {
clients.remove(i);
Politeknik Negeri Sriwijaya
Niki Astri | Teknik Komputer
System.out.println("Disconnected Client " + ct.username + "
removed from list.");
}
}
}
private String getClients() {
String s = "";
for (ClientThread clientThread : clients) {
s += clientThread.username + ":";
}
s += "---";
System.out.println(s);
return s;
}
private synchronized void remove(int id) {
for (int i = 0; i < clients.size(); ++i) {
ChatServer.ClientThread ct = clients.get(i);
if (ct.id == id) {
clients.remove(i);
return;
}
}
}
public static void main(String[] args) {
ChatServer server = new ChatServer();
server.start();
}
private class ClientThread extends Thread {
private Socket socket;
private ObjectInputStream sInput;
private ObjectOutputStream sOutput;
Politeknik Negeri Sriwijaya
Niki Astri | Teknik Komputer
private int id;
private String username;
public ClientThread(Socket socket) {
id = ++uniqueId;
this.socket = socket;
System.out.println("Menciptakan Object Input/Output Streams");
try {
sOutput = new ObjectOutputStream(socket.getOutputStream());
sInput = new ObjectInputStream(socket.getInputStream());
String message = (String) sInput.readObject();
username = message.split("~")[1];
System.out.println(username + " masuk.");
} catch (IOException e) {
System.out.println("Exception creating new Input/output
Streams: " + e);
} catch (ClassNotFoundException e) {
}
}
@Override
public void run() {
boolean keepGoing = true;
while (keepGoing) {
String message;
try {
message = sInput.readObject().toString();
} catch (IOException e) {
System.out.println(username + " Exception reading
Streams: " + e);
break;
} catch (ClassNotFoundException e2) {
break;
}
Politeknik Negeri Sriwijaya
Niki Astri | Teknik Komputer
String type = message.split("~")[0];
String pengirim = message.split("~")[1];
String text = message.split("~")[2];
String kepada = message.split("~")[3];
String response;
switch (type) {
case "postText":
response = "recieveText~" + pengirim + "~" + text + "~" + kepada +
"~\n";
send(response);
break;
case "postPrivateText":
response = "recievePrivateText~" + pengirim + "~" + text + "~" +
kepada + "~\n";
send(response);
break;
case "login":
response = "login~" + pengirim + "~" + text + "~" + kepada +
"~\n";
send(response);
break;
case "logout":
response = "logout~" + pengirim + "~" + text + "~" + kepada +
"~\n";
send(response);
break;
case "list":
response = "list~server~" + getClients() + "~ ~ ~ ~ ~\n";
send(response);
break;
}
}
remove(id);
close();
Politeknik Negeri Sriwijaya
Niki Astri | Teknik Komputer
}
private void close() {
try {
if (sOutput != null) {
sOutput.close();
}
} catch (Exception e) {
}
try {
if (sInput != null) {
sInput.close();
}
} catch (Exception e) {
}
try {
if (socket != null) {
socket.close();
}
} catch (Exception e) {
}
}
private boolean writeMsg(String msg) {
if (!socket.isConnected()) {
close();
return false;
}
try {
sOutput.writeObject(msg);
} catch (IOException e) {
System.out.println("Error sending message to " + username);
System.out.println(e.toString());
}
return true;
}
Politeknik Negeri Sriwijaya
Niki Astri | Teknik Komputer
}
}
2. ChatClient.java
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.table.DefaultTableModel;
public class ChatClient extends javax.swing.JFrame {
/**
* Creates new form ChatClient
*/
private ObjectInputStream input;
private ObjectOutputStream output;
private Socket socket;
private String server, username;
private int port;
private List<String> clients;
public ChatClient() {
clients = new ArrayList();
initComponents();
}
public boolean start() {
Politeknik Negeri Sriwijaya
Niki Astri | Teknik Komputer
try {
socket = new Socket(server, port);
} catch (Exception ec) {
System.out.println("Error connectiong to server:" + ec);
return false;
}
String msg = "Connection accepted " + socket.getInetAddress() +
":" + socket.getPort();
System.out.println(msg);
try {
input = new ObjectInputStream(socket.getInputStream());
output = new ObjectOutputStream(socket.getOutputStream());
} catch (IOException eIO) {
System.out.println("Exception creating new Input/output
Streams: " + eIO);
return false;
}
new ChatClient.ListenFromServer().start();
try {
output.writeObject("login~" + username + "~" + username + "
sedang login...~server~\n");
output.writeObject("list~" + username + "~" + username + "
sedang login...~server~\n");
} catch (IOException eIO) {
System.out.println("Exception doing login : " + eIO);
disconnect();
return false;
}
return true;
}
Politeknik Negeri Sriwijaya
Niki Astri | Teknik Komputer
private void disconnect() {
try {
// TODO add your handling code here:
output.writeObject("logout~" + username + "~" + username +
" sudah logout...~Server~\n");
} catch (IOException ex) {
//Logger.getLogger(ChatClient.class.getName()).log(Level.SEVERE, null,
ex);
}
try {
if (input != null) {
input.close();
}
} catch (Exception e) {
}
try {
if (output != null) {
output.close();
}
} catch (Exception e) {
}
try {
if (socket != null) {
socket.close();
}
} catch (Exception e) {
}
}
/**
* This method is called from within the constructor to initialize
the form.
Politeknik Negeri Sriwijaya
Niki Astri | Teknik Komputer
* WARNING: Do NOT modify this code. The content of this method is
always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
jScrollPane1 = new javax.swing.JScrollPane();
viewTextArea = new javax.swing.JTextArea();
jScrollPane2 = new javax.swing.JScrollPane();
clientTable = new javax.swing.JTable();
postTextField = new javax.swing.JTextField();
kirimButton = new javax.swing.JButton();
lbljpg = new javax.swing.JLabel(new
ImageIcon("D:/nikii.jpg"));
jLabel2 = new javax.swing.JLabel();
serverTextField = new javax.swing.JTextField();
jLabel3 = new javax.swing.JLabel();
portTextField = new javax.swing.JTextField();
masukButton = new javax.swing.JButton();
jLabel4 = new javax.swing.JLabel();
usernameTextField = new javax.swing.JTextField();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
viewTextArea.setEditable(false);
viewTextArea.setColumns(20);
viewTextArea.setLineWrap(true);
viewTextArea.setRows(5);
viewTextArea.setFocusable(false);
jScrollPane1.setViewportView(viewTextArea);
jScrollPane2.setViewportView(clientTable);
Politeknik Negeri Sriwijaya
Niki Astri | Teknik Komputer
postTextField.addActionListener(new
java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt)
{
postTextFieldActionPerformed(evt);
}
});
kirimButton.setText("Kirim");
kirimButton.addActionListener(new
java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt)
{
kirimButtonActionPerformed(evt);
}
});
jLabel2.setText("Server");
serverTextField.setText("127.0.0.1");
jLabel3.setText("Port");
portTextField.setText("9999");
masukButton.setText("Masuk");
masukButton.addActionListener(new
java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt)
{
masukButtonActionPerformed(evt);
}
});
jLabel4.setText("Username");
Politeknik Negeri Sriwijaya
Niki Astri | Teknik Komputer
usernameTextField.setText("niki");
javax.swing.GroupLayout layout = new
javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.
LEADING)
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.
LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING,
layout.createSequentialGroup()
.addComponent(postTextField)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(kirimButton))
.addComponent(jScrollPane1))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE,
259, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGroup(layout.createSequentialGroup()
.addComponent(lbljpg)
.addComponent(jLabel2)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(serverTextField, javax.swing.GroupLayout.PREFERRED_SIZE,
167, javax.swing.GroupLayout.PREFERRED_SIZE)
Politeknik Negeri Sriwijaya
Niki Astri | Teknik Komputer
.addGap(18, 18, 18)
.addComponent(jLabel3)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(portTextField, javax.swing.GroupLayout.PREFERRED_SIZE,
46, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(18, 18, 18)
.addComponent(jLabel4)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(usernameTextField, javax.swing.GroupLayout.DEFAULT_SIZE,
194, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(masukButton)))
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING,
layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.
BASELINE)
.addComponent(lbljpg)
.addComponent(jLabel2)
.addComponent(serverTextField, javax.swing.GroupLayout.PREFERRED_SIZE,
javax.swing.GroupLayout.DEFAULT_SIZE,
javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jLabel3)
.addComponent(portTextField, javax.swing.GroupLayout.PREFERRED_SIZE,
javax.swing.GroupLayout.DEFAULT_SIZE,
javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(masukButton)
Politeknik Negeri Sriwijaya
Niki Astri | Teknik Komputer
.addComponent(jLabel4)
.addComponent(usernameTextField,
javax.swing.GroupLayout.PREFERRED_SIZE,
javax.swing.GroupLayout.DEFAULT_SIZE,
javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.
LEADING)
.addComponent(jScrollPane2, javax.swing.GroupLayout.Alignment.TRAILING,
javax.swing.GroupLayout.DEFAULT_SIZE, 427, Short.MAX_VALUE)
.addGroup(layout.createSequentialGroup()
.addComponent(jScrollPane1)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.
BASELINE)
.addComponent(postTextField, javax.swing.GroupLayout.PREFERRED_SIZE,
javax.swing.GroupLayout.DEFAULT_SIZE,
javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(kirimButton))))
.addContainerGap())
);
pack();
}// </editor-fold>
private void masukButtonActionPerformed(java.awt.event.ActionEvent
evt) {
// TODO add your handling code here:
this.server = serverTextField.getText();
this.port = new Integer(portTextField.getText());
this.username = usernameTextField.getText();
start();
Politeknik Negeri Sriwijaya
Niki Astri | Teknik Komputer
}
private void kirimButtonActionPerformed(java.awt.event.ActionEvent
evt) {
// TODO add your handling code here:
try {
String message = "postText~" + username + "~" +
postTextField.getText() + "~all~\n";
output.writeObject(message);
postTextField.setText("");
} catch (IOException ex) {
Logger.getLogger(ChatClient.class.getName()).log(Level.SEVERE, null,
ex);
}
}
private void
postTextFieldActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
kirimButtonActionPerformed(evt);
}
/**
* @param args the command line arguments
*/
public static void main(String args[]) {
/* Set the Nimbus look and feel */
//<editor-fold defaultstate="collapsed" desc=" Look and feel
setting code (optional) ">
/* If Nimbus (introduced in Java SE 6) is not available, stay
with the default look and feel.
* For details see
http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.htm
l
*/
Politeknik Negeri Sriwijaya
Niki Astri | Teknik Komputer
try {
for (javax.swing.UIManager.LookAndFeelInfo info :
javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException ex) {
java.util.logging.Logger.getLogger(ChatClient.class.getName()).log(java
.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(ChatClient.class.getName()).log(java
.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(ChatClient.class.getName()).log(java
.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(ChatClient.class.getName()).log(java
.util.logging.Level.SEVERE, null, ex);
}
//</editor-fold>
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new ChatClient().setVisible(true);
}
});
Politeknik Negeri Sriwijaya
Niki Astri | Teknik Komputer
}
// Variables declaration - do not modify
private javax.swing.JTable clientTable;
private javax.swing.JLabel jLabel2;
private javax.swing.JLabel jLabel3;
private javax.swing.JLabel jLabel4;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JScrollPane jScrollPane2;
private javax.swing.JButton kirimButton;
private javax.swing.JButton masukButton;
private javax.swing.JTextField portTextField;
private javax.swing.JTextField postTextField;
private javax.swing.JTextField serverTextField;
private javax.swing.JTextField usernameTextField;
private javax.swing.JTextArea viewTextArea;
private JLabel lbljpg ;
// End of variables declaration
class ListenFromServer extends Thread {
@Override
public void run() {
while (true) {
try {
String msg = (String) input.readObject();
String res;
String type = msg.split("~")[0];
String pengirim = msg.split("~")[1];
String text = msg.split("~")[2];
String kepada = msg.split("~")[3];
switch (type) {
case "recieveText":
res = pengirim + ": " + text;
viewTextArea.setText(viewTextArea.getText()
+ res + "\n");
break;
Politeknik Negeri Sriwijaya
Niki Astri | Teknik Komputer
case "recievePrivateText":
res = pengirim + ": " + text;
if (kepada.equals(username)) {
viewTextArea.setText(viewTextArea.getText() + res + "\n");
}
break;
case "login":
viewTextArea.setText(viewTextArea.getText()
+ pengirim + " sedah login..." + "\n");
clients.add(pengirim);
break;
case "logout":
viewTextArea.setText(viewTextArea.getText()
+ pengirim + " telah logout..." + "\n");
clients.remove(pengirim);
break;
case "list":
setTable(text);
break;
}
} catch (IOException e) {
System.out.println("Server has close the
connection: " + e);
break;
} catch (ClassNotFoundException e2) {
}
}
}
private void setTable(String text) {
int rows = text.split(":").length - 1;
Object[][] data = new Object[rows][1];
for (int i = 0; i < rows; i++) {
String t = text.split(":")[i];
data[i][0] = t;
Politeknik Negeri Sriwijaya
Niki Astri | Teknik Komputer
}
String[] header = {"Clients"};
clientTable.setModel(new DefaultTableModel(data, header));
}
}
}
Jika kedua program telah selesai dibuat maka kita compile program tersebut dengan
menekan tombol CTRL + 1. Jika progam tidak memiliki kesalahan akan timbul pesan Tool
Compiled Successfully. Kemudian jalankan program. Adapun hasil programnya adalah sebagai
berikut :
1. Tampilan ketika server menerima client yang telah masuk ke server.
Gambar 1. Ketika client telah masuk ke server
Politeknik Negeri Sriwijaya
Niki Astri | Teknik Komputer
2. Tampilan ketika client berhasil masuk ke server.
Gambar 2. Ketika client berhasil masuk ke server.
3. Tampilan ketika client melakukan chatting
Gambar 3. Ketika client berhasil masuk dan melakukan chatting.
Politeknik Negeri Sriwijaya
Niki Astri | Teknik Komputer
4. Ketika client berhasil masuk ke server.
Gambar 4. Ketika client berhasil masuk dan melakukan chatting.