Materi IV Java Socket
Materi IV Java Socket
I. Tentang Socket
Socket adalah sebuah abstraksi perangkat lunak yang digunakan sebagai suatu "terminal" dari
suatu hubungan antara dua mesin atau proses yang saling berinterkoneksi.
Di tiap mesin yang saling berinterkoneksi, harus terpasang socket.
Socket biasa digunakan untuk pemrograman berbasis client-server yang dapat menggunakan
socket TCP atau socket UDP
Pada J2SE telah disediakan paket java.net yang berisi kelas-kelas dan interface yang
menyediakan API (Application Programming Interface) level rendah (Socket, ServerSocket,
DatagramSocket) dan level tinggi (URL, URLConnection).
Socket adalah mekanisme komunikasi yang memungkinkan terjadinya pertukaran data antar
program atau proses baik dalam satu mesin maupun antar mesin.
Socket akan membangun komunikasi antar proses yang sama-sama aktif.
II. Kelas Socket
Sebuah kelas yang digunakan oleh Client untuk inisialisasi koneksi dengan server (kelas
ServerSocket) menggunakan protocol TCP. Ketika sebuah socket dibuat, maka sebuah koneksi
akan terbentuk ke suatu mesin atau proses yang dituju.
Pada java, kelas Socket memiliki kurang lebih 8 buah konstruktor berikut ini contoh-contoh
konstruktornya:
1. Socket(InetAddress address, int port)
Membuat sebuah stream socket dan koneksi ke suatu nomor port pada suatu computer yang
memiliki alamat IP.
2. Socket(String Host, int port)
Membuat stream socket dan juga koneksi ke suatu port computer berdasarkan nama
komputernya.
3. Socket(String host, int port, InetAddress localAddr, intlocal Port); atau Socket(String
host, int port, InetAddress localAddr, intlocal Port);
Membuat sebuah socket dan mengkoneksikannya ke port yang dituju pada alamat IP yang
disebutkan pada parameter address atau namahost berikut melakukan bind socket ke alamat
local dan port lokal.(Jika koneksi antara client dan server membutuhkan nomor port yang
sudah ditentukan.
4. Dan lain-lain.
Selain konstruktor terdapat beberapa method dari kelas Socket yaitu:
1. getInputStream(), akan mengembalikan objek input stream dari socket yang dapat
ditampung pada objek dari kelas DataInputStream.
2. getOutputStream(), akan mengembalikan objek output stream ke socket yang dapat
ditampung pada objek dari kelas DataOutputStream.
3. close(), digunakan untuk memberitahukan ke protocol untuk menutup koneksi.
4. getInetAddress(), digunakan untuk mendapatkan nama host yang dituju dan alamat IP-nya.
5. getPort(), digunakan untuk mendapatkan nomor port remote host.
6. getLocalPort(), digunakan untuk mendapatkan nomor port localhost.
7. getLocalAddress(), digunakan untuk mendapatkan alamat local dimana socket digunakan.
8. setSoTimeout(int timeout) dan getSoTimeOut(), kedua method tersebut digunakan untuk
memberi(set) dan mengambil(get) nilai opsi Socket untuk time out block
reading(dalammilidetik) dari socket(SO_TIMEOUT). Jika dalam waktu time out tidak
mendapat suatu nilai maka, akan dilemparkan ke exception
java.net.SocketTimeoutException. Nilai default timeout-nya adalah 0, yang berarti tanpa
batas.
9. setTCPNoDelay(Boolean on) dan getTCPNoDelay(), kedua method ini digunakan untuk
memberi dan mengambil nilai opsi Socket TCP_NODELAY. TCP_NODELAY yaitu untuk
mengaktifkan atau menonaktifkan Algoritma Nagle(RFC896), yaitu algoritma yang membuat
TCP lebih efisien dalam konsumsi bandwidth dengan cara memperlambat penulisan data
dalam ukuran yang kecil sehingga data-data yang ada dapat terkirimkan dalam suatu paket
dengan ukuran besar. Nilai default opsi ini adalah aktif. Namun jika diinginkan adanya
pengurangan network latency(waktu delay dalam pengiriman paket) dan meningkatkan unjuk
kerja, maka opsi ini harus dinonaktifkan(di set dengan nilai false), namun akibatnya
konsumsi bandwidth akan bertambah besar.
10. setSoLinger(Boolean on, int linger) dan getSoLinger(), method tersebut akan
mengaktifkan(true) atau menonaktifkan(false) opsi SO_LINGER dengan nilai waktu linger
dalam milidetik. Opsi ini berpengaruh ketika socket ditutup, yaitu menentukan nilai waktu
maksimum koneksi yang masih akan dipertahankan sampai socket koneksi benar-bernar
ditutup. Hal ini berguna untuk mengirim dan memberikan ACK(acknowledge) terhadap data
yang belum terkirim.
11. setSendBufferSize(int size) dan getSendBufferSize(), method ini akan mengatur dan
mengambil informasi tentang ukuran buffer SO_SNDBUF, yaitu buffer untuk pengiriman.
Ukuran ini juga harus disesuaikan ukuran buffer pada level network.
12. setReceiveBufferSize(intsize) dan getReceiveBufferSize(), method ini digunakan jika Anda
ingin mengatur ukuran buffer SO_RCVBUF, yaitu buffer yang digunakan untuk menampung
paket yang masuk. Ukuran buffer ini juga digunakan untuk mengatur ukuran window yang
diterapkan oleh TCP untuk flowcontrolnya(slidingwindow). Dalam pemanfaatan opsi ini,
perlu dipastikan antara RCVBUF client dengan server ada sinkronisasi, sehingga sebelum
server membind port yang akan digunakan ke socket(TCP) ataupun sebelum client membuk
akoneksi ke server, terlebih dahulu opsi ini harus diatur, jika Anda ingin mengaturnya.
Contoh penggunaan kelas Socket.
import java.io.*;
import java.net.*;
public class ExHTTPClient
{
public static void main(String args[])
{
try
{
Socket clientSocket = new Socket("localhost", 80);
System.out.println("Client: "+ clientSocket);
System.out.println("###########################");
getHTML(clientSocket,"/test.html");
}
catch (UnknownHostException e)
{
System.out.println(e);
}
catch (IOException e)
{
System.err.println(e);
}
}
public static void getHTML(Socket clientSocket, String fileName)
{
try
{
DataOutputStream outbound = new DataOutputStream(clientSocket.getOutputStream() );
DataInputStream inbound = new DataInputStream(clientSocket.getInputStream() );
outbound.writeBytes("GET "+ fileName + " HTTP/1.0\r\n\r\n");
String responseLine;
while ((responseLine = inbound.readLine()) != null)
{
System.out.println(responseLine);
}
outbound.close();
inbound.close();
clientSocket.close();
}
catch (IOException e)
{
System.out.println(e);
}
}
}
File test.html
<html>
<head>
<title>Test Dokumen HTML</title>
</head>
<body bgcolor="lavender">
<b>Test Dokumen HTML yang Pertama</b>
</body>
</html>
III. ServerSocket
Digunakan oleh Server untuk listen koneksi dari klien menggunakan protocol TCP, dimana
setelah client terkoneksi ke server dengan menggunakan Socket, maka ServerSocket akan
mengembalikan status server ke client melalui koneksi yang terbentuk sebelumnya. Tipe koneksi
aplikasi yang dibangun dengan kelas ServerSocket ini adalah Connection Oriented.
Ketika dibuat objek baru dari kelas ServerSocket, agar dapat mengirim dan menerima melalui
stream, tetap perlu dibuat InputStream dan OutputStream dari objek Socket yang dihasilkan
ketika dari kelas ServerSocket menerima permintaan dari client melalui method accept().
Kelas ServerSocket memiliki suatu konstruktor yang menerima sebuah nomor Port yang akan
digunakan sebagai nomor akses layanan yang disediakannya, yaitu:
ServerSocket( int port [, int backlog [, InetAddress bindAddress ]] );
Konstruktor diatas membuat sebuah server dengan port tertentu, batasan jumlah antrian
(backlog), dan alamat IP bindAddress.
Serupa dengan kelas Socket, pada kelas ServerSocket juga menyediakan beberapa method ini:
1. accept(), akan menghasilkan sebuah objek kelas Socket yang terkoneksi dengan klien.
2. close(), akan menutup sesi listen untuk permintaan yang datang dari socket client.
IV. Penanganan kegagalan
Penanganan terhadap suatu kegagalan dalam berinterkoneksi dengan socket dapat dilakukan
dengan menangkap kegagalan tersebut dalam blok perintah:
try
{
//perintah-perintah yang dikerjakan
}
catch(KelasException objek)
{
//perintah-perintah yang dikerjakan jika ada kegagalan dari satu perintah
//di dalam blok try
}
Terdapat beberapa kelas penanganan kegagalan atau disebut dengan kelas Exception, karena
kelas-kelas ini merupakan turunan dari kelas Exception. Berikut ini kelas-kelas Exceptionnya:
1. SocketException
Kelas ini merupakan kelas yang diturunkan dari kelasIOException. Kelas exception ini
dipanggil atau dipicu ketika ada kegagalan dalam pemakaian socket, sebagai contoh adalah
kegagalan dalam protokol TCP. Salah satu penyebabnya yang mungkin terjadi adalah ketika
port yang akan digunakan sudah digunakan sebelumnya pada lokalhost. Penyebab yang lain
adalah user tidak dapat melakukan bind ke port yang dituju. Misalnya saja, Anda ingin
menggunakan port 80 untuk aplikasi Anda, namun ternyata pada komputer Anda tersebut
sudah berjalan HTTP Server yang juga menggunakan port 80. Bila hal ini terjadi, maka JVM
akan melemparkan kegagalan yang ada ke kelas exception SocketException.
2. BindException
Exception ini akan dipanggil ketika ada port lokal yang akan digunakan sudah terpakai oleh
yang lain, atau ada kegagalan dalam permintaan untuk menggunakan alamat.
3. ConnectException
Exception ini akan dipanggil ketika sebuah koneksi ditolak oleh host yang dituju, oleh karena
tidak ada proses yang siap menerima data pada port yang dituju.
4. NoRouteToHostException
Koneksi yang akan dibangun tidak dapat dipenuhi oleh karena melebihi waktu timeout yang
tersedia atau host yang dituju tidak dapat dicapai (unreachable).
Contoh aplikasi yang menggunakan kelas ServerSocket dan penanganan kelas.
Program Server
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.Date;
public class ProgramServer {
private final int NOMOR_PORT=8080;
private String dataDariClient;
public ProgramServer(){
BufferedReader inputDariClient;
DataOutputStream outputKeClient;
Socket serverSocket;
try {
ServerSocket infoServer = new ServerSocket(NOMOR_PORT);
System.out.println("Server telah siap...!");
while(true){
serverSocket = infoServer.accept();
System.out.println("Ada client yang terkoneksi...!");
inputDariClient = new BufferedReader(new
InputStreamReader(serverSocket.getInputStream()) );
outputKeClient = new DataOutputStream(serverSocket.getOutputStream());
outputKeClient.writeBytes("InfoServer versi0.1\n"+
"hanya untuk testing..\n"+
"Silahkan berikan perintah TIME|NET|Quit\n");
boolean isQUIT = false;
while (!isQUIT)
{
dataDariClient = inputDariClient.readLine();
if(dataDariClient.startsWith("TIME"))
{
outputKeClient.writeBytes(new Date().toString()+"\n");
}
else if (dataDariClient.startsWith("NET"))
{
outputKeClient.writeBytes(InetAddress.getByName ("localhost").toString()+"\n");
}
else if(dataDariClient.startsWith("QUIT")){
isQUIT = true;
}
}
outputKeClient.close();
inputDariClient.close();
serverSocket.close();
}
}
catch(SocketException soe){
System.out.println("Port Socketnya telah digunakan silahkan ganti nomor portnya");
}
catch(IOException ioe){
System.out.println("Error:" +ioe);
}
catch(Exception e){
System.out.println("Error:" +e);
}
}
public static void main(String[] args) {
new ProgramServer();
}
}
Program Klien
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
public class ProgramClient {
private final int NOMOR_PORT=1234;
private final String TARGET_HOST="localhost";
private final String QUIT="QUIT";
public ProgramClient(){
try{
BufferedReader inputDariUser = new BufferedReader(new
InputStreamReader(System.in) );
Socket clientSocket = new Socket(TARGET_HOST,NOMOR_PORT );
DataOutputStream outputKeServer = new
DataOutputStream(clientSocket.getOutputStream() );
BufferedReader inputDariServer = new BufferedReader(new
InputStreamReader(clientSocket.getInputStream()) );
System.out.println(inputDariServer.readLine());
System.out.println(inputDariServer.readLine());
System.out.println(inputDariServer.readLine());
boolean isQUIT = false;
while (!isQUIT){
System.out.print("Perintah Anda :");
String cmd = inputDariUser.readLine();
cmd = cmd.toUpperCase();
if (cmd.equals(QUIT)){
isQUIT = true;
}
outputKeServer.writeBytes(cmd +"\n");
String result = inputDariServer.readLine();
System.out.println("Dari Server :"+ result);
}
outputKeServer.close();
inputDariServer.close();
clientSocket.close();
}
catch (IOException ioe){
System.out.println("Error:"+ioe);
}
catch (Exception e){
System.out.println("Error:"+e);
}
}
public static void main(String[] args) {
new ProgramClient();
}
}
Daftar Pustaka:
http://zulvkr.multiply.com/journal/item/1?&show_interstitial=1&u=%2Fjournal%2Fitem
http://lecturer.eepis-its.edu/~yuliana/Prog%20Lanjut/Networking/socket.pdf
Budi Susanto, Pemrograman Client/Server dengan Java 2, Elex Media Komputindo,
2003.