Program
Server code:
import socket
import threading
import time
import logging
HOST = ''
PORT = 8018
TIMEOUT = 5
BUF_SIZE = 1024
class
WhatsUpServer(threading.Thread):
def __init__(self, conn, addr):
threading.Thread.__init__(self)
self.conn = conn
self.addr = addr
self.ip = self.addr[0]
self.name = ''
def print_indicator(self, prompt):
self.conn.send('%s\n>> ' %
(prompt,))
def login(self):
global clients
global messages
global accounts
global onlines
logging.info('Connected from: %s:%s' %
(self.addr[0],
self.addr[1]))
clients.add((self.conn, self.addr))
msg = '\n## Welcome to WhatsUp\n##
Enter `!q` to quit\n'
# new user
print accounts
if self.ip not in accounts:
msg += '## Please enter your name:'
self.print_indicator(msg)
accounts[self.ip] = {
'name': '',
'pass': '',
'lastlogin':
time.ctime()
}
while 1:
name =
self.conn.recv(BUF_SIZE).strip()
if name in messages:
self.print_indicator(
'## This name already exists,
please try another')
else:
break
accounts[self.ip]['name'] = name
self.name = name
logging.info('%s logged as %s' %
(self.addr[0], self.name))
messages[name] = []
self.print_indicator(
'## Hello %s, please enter your
password:' % (self.name,))
password = self.conn.recv(BUF_SIZE)
accounts[self.ip]['pass'] =
password.strip()
self.print_indicator('## Welcome,
enjoy your chat')
else:
self.name =
accounts[self.ip]['name']
msg += '## Hello %s, please enter
your password:' % (self.name,)
# print accounts
self.print_indicator(msg)
while 1:
password =
self.conn.recv(BUF_SIZE).strip()
if password !=
accounts[self.ip]['pass']:
self.print_indicator(
'## Incorrect password,
please enter again')
else:
self.print_indicator(
'## Welcome back, last
login: %s' %
(accounts[self.ip]['lastlogin'],))
accounts[self.ip]['lastlogin'] = time.ctime()
break
self.conn.send(self.show_mentions(self.name))
self.broadcast('`%s` is online now' %
(self.name,), clients, False)
onlines[self.name] = self.conn
def logoff(self):
global clients
global onlines
self.conn.send('## Bye!\n')
del onlines[self.name]
clients.remove((self.conn, self.addr))
if onlines:
self.broadcast('## `%s` is offline
now' %
(self.name,),
clients)
self.conn.close()
exit()
def check_keyword(self, buf):
global onlines
if buf.find('!q') == 0:
self.logoff()
if buf.find('#') == 0:
group_keyword = buf.split('
')[0][1:]
group_component =
group_keyword.split(':')
# to post in a group
if len(group_component) == 1:
group_name = group_component[0]
try:
msg = '[%s]%s: %s' % (
group_name, self.name,
buf.split(' ', 1)[1])
self.group_post(group_name,
msg)
except IndexError:
self.print_indicator(
'## What do you want to
do with `#%s`?' % (group_name))
# to join / leave a group
elif len(group_component) == 2:
group_name = group_component[0]
if group_component[1] ==
'join':
self.group_join(group_name)
elif group_component[1] ==
'leave':
self.group_leave(group_name)
return True
if buf.find('@') == 0:
to_user = buf.split(' ')[0][1:]
from_user = self.name
msg = buf.split(' ', 1)[1]
# if user is online
if to_user in onlines:
onlines[to_user].send('@%s:
%s\n>> ' % (from_user, msg))
self.mention(from_user,
to_user, msg, 1)
# offline
else:
self.mention(from_user,
to_user, msg)
return True
def group_post(self, group_name, msg):
global groups
# if the group does not exist, create
it
groups.setdefault(group_name, set())
# if current user is a member of the
group
if (self.conn, self.addr) in
groups[group_name]:
self.broadcast(msg,
groups[group_name])
else:
self.print_indicator(
'## You are current not a
member of group `%s`' % (group_name,))
def group_join(self, group_name):
global groups
groups.setdefault(group_name, set())
groups[group_name].add((self.conn,
self.addr))
self.print_indicator('## You have
joined the group `%s`' %
(group_name,))
def group_leave(self, group_name):
global groups
try:
groups[group_name].remove((self.conn, self.addr))
self.print_indicator('## You have
left the group `%s`' %
(group_name,))
except Exception, e:
pass
def mention(self, from_user, to_user, msg,
read=0):
global messages
# print 'Messages', messages
if to_user in messages:
messages[to_user].append([from_user, msg, read])
self.print_indicator('## Message
has sent to %s' % (to_user,))
else:
self.print_indicator('## No such
user named `%s`' % (to_user,))
def show_mentions(self, name):
global messages
res = '## Here are your messages:\n'
if not messages[name]:
res += ' No messages available\n>> '
return res
for msg in messages[name]:
if msg[2] == 0:
res += '(NEW) %s: %s\n' %
(msg[0], msg[1])
msg[2] = 1
else:
res += ' %s: %s\n' % (msg[0], msg[1])
res += '>> '
return res
def broadcast(self, msg, receivers,
to_self=True):
for conn, addr in receivers:
# if the client is not the current
user
if addr[0] != self.ip:
conn.send(msg + '\n>> ')
# if current user
else:
self.conn.send('>> ') if
to_self else self.conn.send('')
def run(self):
global messages
global accounts
global clients
self.login()
while 1:
try:
self.conn.settimeout(TIMEOUT)
buf =
self.conn.recv(BUF_SIZE).strip()
logging.info('%s@%s: %s' %
(self.name, self.addr[0], buf))
# check features
if not self.check_keyword(buf):
# client broadcasts message
to all
self.broadcast('%s: %s' %
(self.name, buf), clients)
except Exception, e:
# timed out
pass
def main():
global clients
global messages
global accounts
global onlines
global groups
# logging setup
logging.basicConfig(level=logging.INFO,
format='[%(asctime)s]
%(levelname)s: %(message)s',
datefmt='%d/%m/%Y
%I:%M:%S %p')
# initialize global vars
clients = set()
messages = {}
accounts = {}
onlines = {}
groups = {}
# set up socket
sock = socket.socket(socket.AF_INET,
socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET,
socket.SO_REUSEADDR, 1)
sock.bind((HOST, PORT))
sock.listen(5)
print '>> Listening on:', PORT
print ''
while 1:
try:
conn, addr = sock.accept()
server = WhatsUpServer(conn, addr)
server.start()
except Exception, e:
print e
if __name__ == '__main__':
try:
main()
except KeyboardInterrupt:
print
'Quited'
Client Code:
import socket
import time
import logging
import sys
HOST = '192.168.5.31'
PORT = 8018
TIMEOUT = 5
BUF_SIZE = 4096
class WhatsUpClient():
def __init__(self, host=HOST, port=PORT):
self.sock =
socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.connect((host, port))
logging.info('Connecting to %s:%s' %
(host, port))
while 1:
try:
buf = self.sock.recv(BUF_SIZE)
sys.stdout.write(buf)
cmd = raw_input()
if cmd.strip() == '!q':
sys.exit(1)
self.sock.send(cmd)
except:
self.sock.close()
def run(self):
pass
def main():
logging.basicConfig(level=logging.INFO,
format='[%(asctime)s] %(levelname)s:
%(message)s',
datefmt='%d/%m/%Y
%I:%M:%S %p')
client = WhatsUpClient()
if __name__ == '__main__':
main()
Output:
Server Terminal:
[exam10@localhost 3317]$ cd chat/
[exam10@localhost chat]$ python
ser2.py
>> Listening on: 8018
[17/03/2015 02:50:52 PM] INFO:
Connected from: 192.168.5.20:36135
{}
[17/03/2015 02:51:03 PM] INFO:
192.168.5.20 logged as smrutee
[17/03/2015 02:51:14 PM] INFO:
smrutee@192.168.5.20: hi all
[17/03/2015 02:51:20 PM] INFO:
Connected from: 192.168.5.31:46021
{'192.168.5.20': {'name':
'smrutee', 'lastlogin': 'Tue Mar 17 14:50:52 2015', 'pass': '456'}}
[17/03/2015 02:51:25 PM] INFO:
192.168.5.31 logged as manju
[17/03/2015 02:51:35 PM] INFO:
manju@192.168.5.31: hello
[17/03/2015 02:51:56 PM] INFO:
smrutee@192.168.5.20: hey
[17/03/2015 02:52:02 PM] INFO:
smrutee@192.168.5.20: 'hi manju
[17/03/2015 02:52:50 PM] INFO:
Connected from: 192.168.5.38:41157
{'192.168.5.20': {'name':
'smrutee', 'lastlogin': 'Tue Mar 17 14:50:52 2015', 'pass': '456'},
'192.168.5.31': {'name': 'manju', 'lastlogin': 'Tue Mar 17 14:51:20 2015',
'pass': '123'}}
[17/03/2015 02:52:56 PM] INFO:
192.168.5.38 logged as piyush
[17/03/2015 02:53:00 PM] INFO:
piyush@192.168.5.38: hi manju
[17/03/2015 02:53:04 PM] INFO: manju@192.168.5.31: how
are you
Client Terminal:
[exam10@localhost chat]$ python
cli2.py 192.168.5.31 8018
[17/03/2015 02:51:20 PM] INFO:
Connecting to 192.168.5.31:8018
## Welcome to WhatsUp
## Enter `!q` to quit
## Please enter your name:
>> manju
## Hello manju, please enter your
password:
>> 123
## Welcome, enjoy your chat
>> hello
>>
smrutee: hey
>> how are you
smrutee: 'hi manju
>> `piyush` is online now
>> piyush: hi manju
>> hi
No comments:
Post a Comment