simple chat server in python

Bosan!

Lagi pengen cari hiburan. Akhirnya ngoprek python yang mrogramnya headache-free. Biar seru pygame dipilih sebagai mainan. Hasil akhirnya game pesawat-pesawatan SHMUP-defense yang dipublish di sini yang dibuat dalam waktu 1 hari (gambarnya udah dibikin di project lain yang platformnya j2me).

Biar belajar sesuatu yang baru tapi masih berkaitan sama tugas kuliah (distributed shared memory bwt wireless embedded network sama simulasi berbasis agen) akhirnya diputuskan pengen bikin MMO yang as-simple-as-possible pake python. Lagi penasaran aja pake socket di python. ternyata cukup sederhana, mungkin bisa dibilang lebih sederhana dari socket di JAVA. habis baca tutorialnya langsung bikin echo server, dengan tambahan. di client, untuk nerima message dari client yang lain nggak harus nunggu input seperti yang ada di sini.

"""
	file : server.py
	auth : Pebbie
	desc : echo server, multithreaded
"""
import socket, threading
import os, sys

BACKLOG = 5
class Server:
	def __init__(self,host='',port=8080,size=1024):
		self.host = host
		self.port = port
		self.size = size
		self.socket = None
		self.threads = []
		self.run()

	def open(self):
		try:
			self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
			self.socket.bind((self.host,self.port))
			self.socket.listen(BACKLOG)
		except socket.error(value, message):
			if self.socket:
				self.socket.close()
			print "create socket failed : ", message
			sys.exit(1)

	def run(self):
		self.open()
		running = True
		while running:
			c = Client(self, self.socket.accept())
			self.threads.append(c)
			c.start()
		self.close()

	def close(self):
		self.socket.close()
		for c in self.threads:
			c.join()

	def send(self,msg):
		for c in self.threads:
			c.client.send(msg)

class Client(threading.Thread):
	def __init__(self,owner,(client,address)):
		threading.Thread.__init__(self)
		self.owner = owner
		self.client = client
		self.address = address
		self.size = 1024
		self.running = False

	def close(self):
		try:
			self.owner.threads.remove(self)
			self.owner.send("quit")
			self.client.close()
		except:
			pass
		self.running = False
		print "closing ", self.address

	def run(self):
		self.running = True
		while self.running:
			try:
				data = self.client.recv(self.size)
				if data:
					print "received from ", self.address, data
					self.interpret(data)
				else:
					self.close()
			except:
				self.close()

	def interpret(self,msg):
		if msg == "stop":
			self.client.send(msg)
			self.close()
		else:
			self.owner.send(msg)

if __name__=='__main__':
	s = Server()

Tadinya di contoh kode Python network programming ada kode yang pakai modul select, tapi entah kenapa selalu aja exception ketika objek yang dimasukinnya sys.stdin. mungkin ada yang pernah pengalaman bisa bantu?

berikutnya kode untuk client

"""
	file : client.py
	auth : pebbie
	desc : echo client, bisa ngirim untuk client lain
"""
from socket import *
import threading
import os,sys

DATASIZE = 1024
class SocketListener(threading.Thread):
	def __init__(self,owner):
		threading.Thread.__init__(self)
		self.owner = owner
		self.socket = owner.socket
		self.running = False

	def run(self):
		print "listener started"
		self.running = True
		while self.running:
			data = self.socket.recv(self.owner.size)
			print '\nreceived:', data
			if data == "stop":
				self.running = False
		self.socket.close()
		print "disconnected, press return"

class Client:
	def __init__(self,host='localhost',port=8080,size = DATASIZE):
		self.host = host
		self.port = port
		self.size = size
		self.socket = None
		self.listener = None
		self.open()

	def open(self):
		try:
			self.socket = socket(AF_INET, SOCK_STREAM)
			self.socket.connect((self.host,self.port))
		except :
			self.socket = None
			print "something happened, connect failed", msg
			sys.exit(1)
		self.listener = SocketListener(self)
		self.listener.start()

	def run(self):
		while self.listener.running:
			cmd = raw_input()
			if not self.listener.running:
				break
			self.socket.send(cmd)
		self.listener.join()

if __name__=='__main__':
	Client().run()

di client, kode untuk socket.recv dipisah di thread tersendiri. jadi kalau client lain ngirim pesan, pesannya bisa diterima tanpa harus ngetik sesuatu (kekurangan yang ada di contoh pymmo). selanjutnya tinggal penanganan data world & entity, sama game client. rencananya sih untuk manajemen data pake sqlite3 aja yang udah built-in di python 2.5. cara pakai sqlite pun lumayan mudah, tapi dibahasnya nanti aja kalo kode untuk usernya udah jadi. šŸ˜€

7 comments

  1. petra · Mei 6, 2009

    tugas OSL kita cemana…..

    sori baru inget šŸ˜›

  2. latqueire · Mei 7, 2009

    wew great.. belajar java bagus sebagai permulaan untuk SAP.. šŸ˜€

  3. unamedplayer · Mei 19, 2009

    mas-mas map nieh gue bego banget,,

    cara posting kode kaya di atas gimana,,,kan rapih tuh,, gw mau nulis kode hml/javascript tapi gak muncul semua

  4. Arif Hidayatullah · Oktober 9, 2013

    saya coba di python 2.7.3 kok nggk bisa ya?
    nggk ada error, cuma keluar “listener started”, tp antar klien nggk bisa saling mengirim pesan..
    itu gimana, mohon bantuannya?
    anda menggunakan python berapa?
    apa anda hanya menggunakan linux atau windows?
    Terima kasih..

    • pebbie · Oktober 10, 2013

      kalau tidak salah ingat, saya buatnya di python 2.5 win32, barusan saya cek di 2.7 juga tidak jalan. Ada yang salah di kodenya juga.

  5. Arif Hidayatullah · Oktober 11, 2013

    terus ada sourcode yang sudah fix nggk pak yang bisa dicoba pake python 2.7?

Tinggalkan komentar

Situs ini menggunakan Akismet untuk mengurangi spam. Pelajari bagaimana data komentar Anda diproses.