Network Programming in Python and Graphics

DON'T post new tutorials here! Please use the "Pending Submissions" board so the staff can review them first.
Post Reply
User avatar
maboroshi
Dr. Mab
Dr. Mab
Posts: 1624
Joined: 28 Aug 2005, 16:00
18

Network Programming in Python and Graphics

Post by maboroshi »

Network Programming in Python and Graphics


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
Our import statements you will notice we import our GUI modules, our socket modules, threading for keeping the GUI from freezing during connections. Finally cPickle his allows to send binary data over the network

Code: Select all

CMD_MSG, CMD_LINE = range(2)
create some global variables

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
next we create our loop

Code: Select all

    while True:
        msg, addr = s.recvfrom(2024)
        cmd, msg = ord(msg[0]),msg[1:]
and listen for any data coming through

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")
if our data is equal to one of our global variables draw or write a message depending on what it equals (You will see soon how we send that data from our client so that the server knows what to interpret)

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)))
this is our messaging function

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')
and here is the actual data were sending

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))
you will notice we are calling our client command and you remember our global variables. So when we call our client function with the global variable our server recognizes it and does what it needs to do

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)
same with our messaging function

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")
our threading code “simple eh”

Code: Select all

mythread = Thread(target=server)
mythread.start()
Now for more GUI code

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() 

and were done

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() 

User avatar
3XTORTION
Fame ! Where are the chicks?!
Fame ! Where are the chicks?!
Posts: 246
Joined: 29 Jul 2007, 16:00
16
Contact:

Post by 3XTORTION »

Nice tutorial Mabs ! Thanks a lot :D

User avatar
F4LSE
Fame ! Where are the chicks?!
Fame ! Where are the chicks?!
Posts: 236
Joined: 02 Jul 2007, 16:00
16
Location: My Lab
Contact:

Post by F4LSE »

I've been trying to get the ball rolling with python programming and havn't been able too. This however has got me thinking and a great start thanks
:D

Post Reply