Pemrograman Socket Dengan Python
Pemrograman Socket Dengan Python
Rikih Gunawan
[email protected]
Lisensi Dokumen:
Copyright © 2003-2006 IlmuKomputer.Com
Seluruh dokumen di IlmuKomputer.Com dapat digunakan, dimodifikasi dan disebarkan
secara bebas untuk tujuan bukan komersial (nonprofit), dengan syarat tidak menghapus
atau merubah atribut penulis dan pernyataan copyright yang disertakan dalam setiap
dokumen. Tidak diperbolehkan melakukan penulisan ulang, kecuali mendapatkan ijin
terlebih dahulu dari IlmuKomputer.Com.
Pendahuluan
Untuk pembuatan aplikasi jaringan, Python menyediakan modul-modul untuk mempermudah
para pembuat program, sehingga para pemrogram lebih memfokuskan diri pada cara kerja dari
programnya tersebut dan yang akan dibahas adalah penggunaan modul socket. Dalam penulisan
ini penulis hanya membahas penggunaan socket dasar di Python dan berasumsi bahwa Anda
minimal telah mengerti konsep jaringan dan dapat menggunakan perintah-perintah dasar
Python.
Masalah pada iterative server adalah ketika sedang menjalankan langkah 2. Selama waktu
tersebut tidak ada client yang dilayani. Sedangkan untuk concurrent server akan melaksanakan
langkah-langkah berikut :
1. Tunggu sampai permintaan (request) dari client tiba.
#!/usr/bin/env python
#Mengimport modul socket
import socket
# Mengimport seluruh konstanta, data, dan method
from socket import *
# Mengimport konstanta
from socket import AF_INET, SOCK_STREAM
Untuk proto bersifat opsional dan biasanya bernilai 0. Untuk membuat socket stream
(TCP) internet domain digunakan statement berikut :
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
Statement di atas akan mengembalikan sebuah tuple (conn, address) dimana conn
adalah objek socket baru yang berguna untuk mengirim dan menerima data dari koneksi, dan
address merupakan alamat dari client.
Statement di atas akan mengembalikan data yang dikirimkan oleh client. Sedangkan untuk
socket datagram :
sock.recvfrom(1024) #Menerima data sebesar 1024 byte
Statement di atas akan mengembalikan dua buah field yaitu data, address.
#!/usr/bin/env python
class Net:
def __init__(self):
# Cek argumen, jika tidak sama dengan 3
# tampilkan cara penggunaan
if len(sys.argv) != 3:
print "Usage: " + sys.argv[0] + " <hostip> <port>"
sys.exit(1)
else:
self.HOST = sys.argv[1] # Set nilai variabel dari
self.PORT = int(sys.argv[2]) # parameter yang diberikan
self.prompt = 'chat> ' # prompt yang akan
ditampilkan
def Create(self):
try:
# Buat socket INET dengan protocol TCP
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
except:
print "Buat socket error..."
else:
# Binding ip dan port
s.bind((self.HOST, self.PORT))
# Mendengarkan koneksi
s.listen(2)
net = Net()
net.Create()
Program diatas merupakan contoh sederhana program jaringan yang menggunakan Internet
Domain dengan protocol TCP. Program ini hanya terdiri dari satu program saja dan berfungsi
sebagai Server. Sedangkan untuk clientnya menggunakan aplikasi Telnet yang ada pada sistem
Anda. Pada saat program dijalankan dan client melakukan koneksi dengan Telnet maka server
akan meminta verifikasi password. Jika client memasukkan password “password” maka
server akan mengirimkan pesan bahwa client telah terkoneksi dan sebaliknya jika client salah
memasukkan password server akan terus meminta password. Perintah-perintah yang dapat
digunakan hanya printah hostname [prompt] untuk mengganti string prompt, dan
keluar untuk memutuskan koneksi dan keluar dari program.
Menjalankan Server
class TCPServer:
def __init__(self):
if len(sys.argv) != 3:
print 'Penggunaan:'+sys.argv[0]+'[ip_address][nomor_port]'
sys.exit(1)
else:
self.HOST = sys.argv[1]
self.PORT = int(sys.argv[2])
def Create(self):
try:
self.sockTCP = socket(AF_INET,SOCK_STREAM) # Buat socket
TCP
self.sockTCP.bind((self.HOST, self.PORT)) # Binding port
self.sockTCP.listen(1) # Listening
except:
print 'Socket error [ip dan port harus valid]'
sys.exit()
else:
print 'Server Message [tekan Ctrl-C untuk keluar]'
print '--------------'
print 'Mendengarkan pada port ' + str(self.PORT)
def Accept(self):
koneksi, alamat = self.sockTCP.accept() # Terima koneksi
print 'Koneksi dari ' + str(alamat)
while 1: # Lakukukan perulangan selama true
data = koneksi.recv(1024)
print 'Pesan dari client >> ' + str(data) # Cetak pesan
client
if not data: break
if len(data) > 1: # Kirim pesan
balik
koneksi.send('[' + str(data) + '] sudah diterima
server.')
def Run(self):
self.Create()
self.Accept()
def __del__(self):
self.sockTCP.close() # Tutup koneksi
if __name__ == '__main__':
msg = TCPServer().Run()
Program diatas merupakan program yang berfungsi sebagai server untuk chatting. Program ini
merupakan server yang bertipe Iterative server, yang berarti hanya dapat menerima dari satu
client/koneksi saja.
class TCPClient:
def __init__(self):
if len(sys.argv) != 3:
print 'Penggunaan: ' + sys.argv[0] + ' [ip_server] [port]'
sys.exit(1)
else:
self.HOST = sys.argv[1]
self.PORT = sys.argv[2]
def Create(self):
try:
self.sockTCP = socket(AF_INET,SOCK_STREAM) # Buat socket
TCP
self.sockTCP.connect((self.HOST, int(self.PORT)))
def Send(self):
try:
while 1:
pesan = raw_input('Pesan : ') # Input pesan
self.sockTCP.send(pesan) # Kirim pesan ke server
data = self.sockTCP.recv(1024)# Terima pesan dari
server
print data # Cetak pesan dari
server
except:
self.__del__()
def Run(self):
self.Create()
self.Send()
def __del__(self):
self.sockTCP.close() # Tutup koneksi
if __name__ == '__main__':
msg = TCPClient().Run()
Program diatas merupakan program client chatting yang digunakan untuk melakukan
koneksi ke server pySChat.py. Client akan melakukan koneksi ke server dan setelah terkoneksi
client dapat mengirimkan pesan ke pada server dan server akan memberikan respon kepada
client.
#!/usr/bin/env python
class ServerWaktu:
def __init__(self):
if len(sys.argv) != 3:
print "penggunaan: " + sys.argv[0] + " <ip_address>
<port>"
sys.exit(1)
else:
self.HOST = sys.argv[1]
self.PORT = int(sys.argv[2])
self.tHostPort = (self.HOST, self.PORT)
def buatSocket(self):
try: # Buat socket UDP
self.tsock = socket(AF_INET, SOCK_DGRAM)
print "Mengikatkan IP dengan port " + str(self.tHostPort)
self.tsock.bind(self.tHostPort)
except:
print "Gagal buat socket"
sys.exit()
def tutupKoneksi(self):
try:
print "Tutup koneksi..."
self.tsock.close()
except:
print "Gagal menerima data"
def __del__(self):
self.tutupKoneksi()
if __name__ == "__main__" :
srv = ServerWaktu()
srv.buatSocket()
srv.tungguKoneksi()
Program ini merupakan program yang berfungsi sebagai time server. Program ini menggunakan
socket Internet dengan menggunakan protocol UDP. Cara kerja program ini adalah setiap ada
koneksi/request dari client maka server akan mengirimkan waktu sistem yang menjalankan
program server tersebut kepada client.
#!/usr/bin/env python
class ClientWaktu:
def __init__(self):
if len(sys.argv) != 3:
print "penggunaan: " + sys.argv[0] + " <ip_address>
<port>"
sys.exit(1)
else:
self.HOST = sys.argv[1]
self.PORT = int(sys.argv[2])
self.tHostPort = (self.HOST, self.PORT)
def buatSocket(self):
try:
self.tsock = socket(AF_INET, SOCK_DGRAM)
print "Hubungi server waktu di " + str(self.tHostPort)
self.tsock.connect(self.tHostPort) # Hubungi server
self.tsock.sendto("", self.tHostPort) # Kirim string
kosong
except:
print "Gagal buat socket"
def terimaData(self):
data, client = self.tsock.recvfrom(100) # Ambil data waktu
def tutupKoneksi(self):
print "Tutup koneksi..."
self.tsock.close()
def __del__(self):
self.tutupKoneksi()
if __name__ == "__main__" :
srv = ClientWaktu()
srv.buatSocket()
srv.terimaData()
#!/usr/bin/env python
class TCPServer:
def __init__(self):
self.path = '/tmp/sock' # Path untuk socket yang akan dibuat
def Create(self):
try:
self.sockUnix = socket(AF_UNIX, SOCK_STREAM) # Buat
socket TCP
self.sockUnix.bind(self.path) # Binding addr dengan port
self.sockUnix.listen(1) # Listening
except:
print 'Socket sudah digunakan...\n\rJika belum, hapus file
'+ \
self.path
sys.exit()
else:
print 'Server Message [tekan Ctrl-C untuk keluar]'
print '--------------'
def Accept(self):
koneksi, alamat = self.sockUnix.accept() # Terima koneksi
print 'Ada koneksi...'
while 1:
try:
data = koneksi.recv(1024) # Terima data
print 'Pesan dari client >> ' + str(data)
if not data: break
if len(data) > 1: # Kirim respon ke client
koneksi.send('[' + str(data)+ '] sudah diterima
server.')
except:
break
def Run(self):
self.Create()
self.Accept()
def __del__(self):
self.sockUnix.close()
os.system('rm -f ' + self.path)
if __name__ == '__main__':
msg = TCPServer().Run()
Program diatas merupakan program chatting. Sebenarnya program diatas sama dengan program
2. Bedanya kalau pada program 2 menggunakan socket Internet sedangkan pada program diatas
menggunakan socket Unix. Seperti yang telah dijelaskan pada bagian awal bahwa pada socket
Unix socket dibuat dalam bentuk file socket disini digunakan file /tmp/sock. Jika pada saat
dijalankan terjadi error coba Anda hapus terlebih dahulu file socket yang ada di /tmp/sock.
Cara kerja programnya adalah server akan menunggu koneksi dari client dan jika ada client
yang menghubungi server maka server akan menerima koneksi tersebut kemudian client dapat
mengirimkan pesan ke server. Setiap pesan yang dikirimkan ke server maka server akan
memberi respon balik ke client. Pada saat program keluar maka program akan menghapus file
socket yang ada di /tmp/sock.
#!/usr/bin/env python
class TCPClient:
def __init__(self):
self.path = '/tmp/sock' # Path untuk melakukan koneksi ke
socket
def Create(self):
try:
self.sockUnix = socket(AF_UNIX, SOCK_STREAM) # Buat socket
UNIX
self.sockUnix.connect(self.path)
except:
print 'Socket error [ip_server dan port harus valid]'
sys.exit()
else:
print 'Client Message'
print '--------------'
def Send(self):
try:
while 1:
pesan = raw_input('Pesan : ') # Meminta input pesan
self.sockUnix.send(pesan) # Mengirim pesan ke client
data = self.sockUnix.recv(1024) # Menerima respon dari
server
print data
except:
self.__del__()
def Run(self):
self.Create()
self.Send()
def __del__(self):
self.sockUnix.close()
if __name__ == '__main__':
msg = TCPClient().Run()
Program diatas merupakan program chatting client. Setiap client mengirimkan pesan ke server
maka server akan mengirimkan respon balik ke client.
#!/usr/bin/env python
lstCmd = ['dir','ls','exit','bye','quit','get','mget',put',
'mput','rm','delete','mv','rename','cd','pwd','chmod',
'cp','copy','rmdir','mkdir','close','disconnect']
hostIP = '127.0.0.1'
hostPort = 1111
filFlag = '*file*'
getFlag = 'get'
if cmd[0] in lstCmd:
if cmd[0] in ['ls','dir']:
if len(cmd) == 1:
cmdS = 'ls -al'
else:
cmdS = 'ls' + ' ' + cmd[1]
ret = commands.getoutput(cmdS)
return ret
class CLI:
def __init__(self):
self.cmd = CMD()
self.childLst = []
def sendFile(self,sock,file):
sock.send(filFlag)
user = os.environ['USER']
command = filFlag
size = os.stat(file)[6]
try:
f = open(file,'r')
except:
ret = 0
else:
pos = 0
while 1:
if pos == 0:
buffer = f.read(5000000-282)
if not buffer: break
count = sock.send(command + ':' + \
string.rjust(os.path.basename(file),214) + ':' + \
string.rjust(str(size).strip(),30) + ':' + \
string.rjust(str(user).strip(),30) + \
buffer)
pos = 1
else:
def recvFile(self,sock):
pjg = 0
msg1 = sock.recv(283).split(':')
flag = msg1[0].strip()
namafile = msg1[1].strip()
total = msg1[2].strip()
user = msg1[3].strip()
file = namafile
if flag == filFlag:
try:
f = open(file,'w')
except:
ret = 0
else:
try:
while 1:
leftToRead = int(total) - pjg
if not leftToRead: break
msg = sock.recv(5000000)
pjg = pjg + len(msg)
f.write(msg)
f.close()
except:
os.remove(file)
ret = 0
else:
ret = 1
ret = 1
return ret
if __name__ == "__main__":
cli = CLI()
cli.runCmd()
lstCmd =
['dir','ls','exit','bye','quit','clear','cls','get','mget',
'put','mput','rm','delete','mv','rename','cd','pwd','chmod',
'cp','copy','?','help','rmdir','mkdir','!','connect','ope
n',
'close','disconnect']
defPort = 1111
filFlag = '*file*'
class IO:
def connect(self, host, port):
try:
print 'Membuat socket...'
self.sockIO = socket(AF_INET, SOCK_STREAM)
except:
print 'Gagal membuat socket !'
ret = 0
else:
try:
print 'Koneksi ke ' + host + ' port ' + str(port)
def sendFile(self,sock,file):
sock.send(filFlag)
user = os.environ['USER']
command = filFlag
size = os.stat(file)[6]
f = open(file,'r')
pos = 0
while 1:
if pos == 0:
buffer = f.read(5000000-282)
if not buffer: break
count = sock.send(command + ':' + \
string.rjust(os.path.basename(file),214) + ':' + \
string.rjust(str(size).strip(),30) + ':' + \
string.rjust(str(user).strip(),30) + \
buffer)
pos = 1
else:
buffer = f.read(5000000)
if not buffer: break
count = sock.send(buffer)
def recvFile(self,sock):
pjg = 0
msg1 = sock.recv(283).split(':')
flag = msg1[0].strip()
namafile = msg1[1].strip()
total = msg1[2].strip()
user = msg1[3].strip()
file = namafile
if flag == filFlag:
try:
f = open(file,'w')
except:
ret = 0
print 'Tidak dapat menyimpan file'
sys.exit()
else:
try:
while 1:
leftToRead = int(total) - pjg
if not leftToRead: break
msg = sock.recv(5000000)
pjg = pjg + len(msg)
f.write(msg)
os.system('echo -n !')
def close(self):
self.sockIO.close()
class CMD:
def __init__(self):
self.getFlag = '*get*'
self.putFlag = '*put*'
self.IO = IO()
self.isConnected = 0
else:
try:
self.Sock.send(cmd0)
ret = 1
except:
print 'Tidak terkoneksi !'
else:
print 'Perintah tidak dikenal.'
return ret
def runCmd(self):
print '\n\r+ + + DrSlump FTP Client + + +\n\r'
while 1:
cmd = raw_input('ftp> ')
if len(cmd.strip()) > 0:
ret = self.checkCmd(cmd)
if self.isConnected and ret == 1:
data = self.Sock.recv(500000)
if data[:len(filFlag)] == filFlag:
ret = self.IO.recvFile(self.Sock)
if ret == 0:
print '\n\rFile gagal di download !'
else:
print '\n\rFile berhasil di download...'
else:
print data
Penjelasan Program
Program FTP Server dan Client diatas merupakan program FTP sederhana. Program diatas
dapat mengirimkan dan menerima file, melakukan operasi file/direktori seperti cd dan mkdir
dan lain-lain. Program server bertipe concurrent server yang dapat melayani banyak client
dengan menggunakan threading.
Penulis menyadari tulisan ini jauh dari sempurna dan bisa dikatakan sangat sederhana,
tetapi Penulis berharap dengan tulisan ini dapat memberikan informasi yang berguna bagi Anda.
Dan jika masih ada kekurangan mohon harap dimaklumi. Saran, kritik dan koreksi sangat
diharapkan. ;)
Referensi
Biografi Penulis
Rikih Gunawan. Tinggal di Serpong, menyelesaikan S1 di universitas
Gunadarma, jurusan Teknik Informatika (2001-2004).