In this Tutorial I will try and explain simple Networking concepts in Python. Some things you will learn here are GUI programming, Networking, threading and hopefully enough understanding to be able to send binary data over the network.
Code: Select all
from Tkinter import *
import socket
from threading import *
import cPickle
Code: Select all
CMD_MSG, CMD_LINE = range(2)
first we define our server function assign a port to listen to and bind it to our IP address
Code: Select all
def server():
port = 9000
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind((socket.gethostbyname(socket.gethostname()), int(port))) # bind to ip
Code: Select all
while True:
msg, addr = s.recvfrom(2024)
cmd, msg = ord(msg[0]),msg[1:]
Code: Select all
if cmd == CMD_LINE: #DRAW A LINE
dx,dy,ex,ey=cPickle.loads(msg)
canvas.create_line(dx,dy,ex,ey,width=2, fill="red")
elif cmd == CMD_MSG:
listb1.insert(END, str(msg) + "\n")
Code: Select all
def client(msg):
port = 9000
host = str(entryhost.get())
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.sendto(str(username.get)+" : " + msg, (host, int(port)))
what it does:
connects to port 9000 on the host (remote computer) and sends a message which we will craft later
These are our drawing functions for drawing lines on a canvas
Code: Select all
def move(e):
global lastLine,mx,my
canvas.delete(lastLine)
mx, my = e.x, e.y
# draw a new temp line
lastLine = canvas.create_line(dx,dy,mx,my,width=2,fill='Black')
def bdown(e):
global lastLine,dx,dy,mx,my
canvas.bind('<Motion>', move) #start receiving move msgs
dx,dy=e.x,e.y
mx,my=e.x,e.y
# draw a temp line
lastLine = canvas.create_line(dx,dy,mx,my,width=2,fill='Black')
Code: Select all
def bup(e):
#canvas.delete(lastLine)
canvas.unbind('<Motion>')
#send out the draw-a-line command
client(chr(CMD_LINE)+cPickle.dumps((dx,dy,e.x,e.y),1))
Code: Select all
def sendit(foo):
client(chr(CMD_MSG) + str(textboxsend.get()))
listb1.insert(1.0, str(textboxsend.get()) + "\n")
textboxsend.delete(0, END)
Some GUI code
Code: Select all
root = Tk()
root.title("Simple P2P Chat App")
root.wm_resizable(0, 0)
root.minsize(550, 400)
#root.wm_iconbitmap("shinobi.ico")
#root.option_readfile("optionDB")
Code: Select all
mythread = Thread(target=server)
mythread.start()
Code: Select all
frame = Frame(root)
entryhost = Entry(frame)
entryhost.pack(side=LEFT, fill=X, expand=True)
entryhost.insert(0, "127.0.0.1")
label = Label(frame, text="Enter IP or Domain")
label.pack(side=LEFT)
username = Entry(frame)
username.pack(side=LEFT, fill=X, expand=True)
label = Label(frame, text="Enter Your Username")
label.pack(side=LEFT)
frame.pack(fill=X)
frame2 = Frame(root)
scrollbar2 = scrollbar2 = Scrollbar(frame2)
scrollbar2.pack(side=LEFT, fill=Y)
listb1 = Text(frame2)
listb1.pack(side=LEFT, fill=BOTH, expand=True)
scrollbar2.config(command=listb1.yview)
listb1.config(yscrollcommand=scrollbar2.set)
canvas = Canvas(frame2, background="white", width=200, height=400)
canvas.pack(side=LEFT)
canvas.bind('<ButtonPress-1>',bdown)
canvas.bind('<ButtonRelease-1>', bup)
frame2.pack(fill=BOTH, expand=True)
frame.pack(fill=BOTH, expand=True)
frame = Frame(root)
textboxsend = Entry(frame)
textboxsend.pack(side=LEFT, fill=X, expand=True)
textboxsend.bind('<Return>',sendit)
textboxsend.focus_set()
label = Label(frame, text="Enter Your Message and Press Enter")
label.pack(side=LEFT)
frame.pack(fill=X)
root.mainloop()
here is the complete source
Code: Select all
### P2P Chat Draw with white board by Maboroshi
from Tkinter import *
import socket
from threading import *
import cPickle
CMD_MSG, CMD_LINE = range(2)
def server():
port = 9000
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind((socket.gethostbyname(socket.gethostname()), int(port)))
#print socket.gethostbyname(socket.gethostname())
while True:
msg, addr = s.recvfrom(2024)
cmd, msg = ord(msg[0]),msg[1:]
if cmd == CMD_LINE: #DRAW A LINE
dx,dy,ex,ey=cPickle.loads(msg)
canvas.create_line(dx,dy,ex,ey,width=2, fill="red")
elif cmd == CMD_MSG:
listb1.insert(END, str(msg) + "\n")
def saveit():
try:
output1 = listb1.get(1.0, END)
str(output1)
try:
filename = tkFileDialog.asksaveasfilename()
except:
pass
entry2.insert(END, filename)
fileit = open(filename, "w")
fileit.write(output1)
except:
listb1.insert(END, "Failed Saving Data\n")
def client(msg):
port = 9000
host = str(entryhost.get())
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.sendto(str(username.get)+" : " + msg, (host, int(port)))
def move(e):
global lastLine,mx,my
canvas.delete(lastLine)
mx, my = e.x, e.y
# draw a new temp line
lastLine = canvas.create_line(dx,dy,mx,my,width=2,fill='Black')
def bdown(e):
global lastLine,dx,dy,mx,my
canvas.bind('<Motion>', move) #start receiving move msgs
dx,dy=e.x,e.y
mx,my=e.x,e.y
# draw a temp line
lastLine = canvas.create_line(dx,dy,mx,my,width=2,fill='Black')
def bup(e):
#canvas.delete(lastLine)
canvas.unbind('<Motion>')
#send out the draw-a-line command
client(chr(CMD_LINE)+cPickle.dumps((dx,dy,e.x,e.y),1))
def sendit(foo):
client(chr(CMD_MSG) + str(textboxsend.get()))
listb1.insert(1.0, str(textboxsend.get()) + "\n")
textboxsend.delete(0, END)
root = Tk()
root.title("Simple P2P Chat App")
root.wm_resizable(0, 0)
root.minsize(550, 400)
#root.wm_iconbitmap("shinobi.ico")
#root.option_readfile("optionDB")
mythread = Thread(target=server)
mythread.start()
frame = Frame(root)
entryhost = Entry(frame)
entryhost.pack(side=LEFT, fill=X, expand=True)
entryhost.insert(0, "127.0.0.1")
label = Label(frame, text="Enter IP or Domain")
label.pack(side=LEFT)
username = Entry(frame)
username.pack(side=LEFT, fill=X, expand=True)
label = Label(frame, text="Enter Your Username")
label.pack(side=LEFT)
frame.pack(fill=X)
frame2 = Frame(root)
scrollbar2 = scrollbar2 = Scrollbar(frame2)
scrollbar2.pack(side=LEFT, fill=Y)
listb1 = Text(frame2)
listb1.pack(side=LEFT, fill=BOTH, expand=True)
scrollbar2.config(command=listb1.yview)
listb1.config(yscrollcommand=scrollbar2.set)
canvas = Canvas(frame2, background="white", width=200, height=400)
canvas.pack(side=LEFT)
canvas.bind('<ButtonPress-1>',bdown)
canvas.bind('<ButtonRelease-1>', bup)
frame2.pack(fill=BOTH, expand=True)
frame.pack(fill=BOTH, expand=True)
frame = Frame(root)
textboxsend = Entry(frame)
textboxsend.pack(side=LEFT, fill=X, expand=True)
textboxsend.bind('<Return>',sendit)
textboxsend.focus_set()
label = Label(frame, text="Enter Your Message and Press Enter")
label.pack(side=LEFT)
frame.pack(fill=X)
root.mainloop()