PLAN
The plan is to make a program using classes that, once executed, will prompt the user for user input. Take the user input and print some information about the user and the user's OS.
First open up IDLE or VI or whatever editor you are using. I am using IDLE and will refer to IDLE from now on. Open up a new window and type in the following. I will be commenting after sections of code so just type the actual code :).
import os, sys
import time
class Info:
def __init__(self, name):
self.username=name
self.opSys=sys.platform
def display(self):
print "%s on %s called this program
"
%(self.username, self.opSys)
def main():
name=raw_input("Enter your name
$")
a=Info(name)
a.display()
print "exiting main"
if __name__=="__main__":
main()
Once you have entered the above simple program, run it. If you are using the python shell on a nix flavor put #!/usr/bin/env python (called "pound bang") in order to execute the file from your nix shell. In the class Info we are instantiating the argument passed to the class with the def __init__(self, name): .
When passing the arguments to the Info class from main, you are passing it to the __init__ methond. Which then instantiates the argument passed along with any other instantiations done within the __init__ section. Notice that the def display(self): , has self as an argument of the function. This is because it is in a class, where as the def main(): does not, since it is not in the nest of a class. Now that we have such a simple example of classes lets do some fun stuff with them. Lets follow the path through what is happening here.
First the program is executed or run and if no errors are encountered, the if __name__=="__main__":
section is executed and within that section main() is called. We then go to the main() function. Prompting the user for their name. Once we have a name we call the Info class, passing to it the user entered name, which we will instantiate. Once the instantiation is done we return to the main() function. Because display is nested within the class Info, we must step through this nest with Info.display, since we already called info in the previous line we assign this to a variable 'a' and use a.display() to call the display function. Notice that we don't pass self to the function. This is because the self is only to satisfiy the class nesting. You do not have to pass self as an arguement unless you are calling from a class or even (sometimes).
Once we print the information from our instantiated objects. We return to the main() function and print our exiting message, thus returning to the if __name__==<"__main__": section. Since no more code is left the program ends.
Sockets
Without going into outright plagarism or redescribing "the wheel" I am providing links to socket definitions and tutorials, mostly the first sections go into various depths in describing the types of sockets etc. Read over them if you are unfamiliar or refer to them after the examples for clarification. I myself havne't used but 2 of them so far, being SOCK_STREAM and SOCK_DGRAM.
http://py-howto.sourceforge.net
http://www.cs.rpi.edu
http://packetstormsecurity.nl
[url=http://www.ecst.csuchico.edu/%7Ebeej/guide/net/html/]http://www.ecst.csuchico.edu
The socket operations provided by python are written in C, as far as I know, and are extremely close if not exactly the same as C. Lets take a look at the socket module:
(in your editor of choice)
>>>import socket
>>>dir(socket)
['AF_APPLETALK', 'AF_INET', 'AF_IPX', 'AF_UNSPEC', 'AI_ADDRCONFIG',
'AI_ALL', 'AI_CANONNAME', 'AI_DEFAULT', 'AI_MASK',
'AI_NUMERICHOST',
'AI_PASSIVE',
'AI_V4MAPPED', 'AI_V4MAPPED_CFG', 'EAI_ADDRFAMILY', 'EAI_AGAIN',
'EAI_BADFLAGS',
'EAI_BADHINTS', 'EAI_FAIL', 'EAI_FAMILY', 'EAI_MAX', 'EAI_MEMORY',
'EAI_NODATA',
'EAI_NONAME', 'EAI_PROTOCOL', 'EAI_SERVICE', 'EAI_SOCKTYPE',
'EAI_SYSTEM',
'INADDR_ALLHOSTS_GROUP',
'INADDR_ANY', 'INADDR_BROADCAST', 'INADDR_LOOPBACK',
'INADDR_MAX_LOCAL_GROUP',
'INADDR_NONE', 'INADDR_UNSPEC_GROUP', 'IPPORT_RESERVED',
'IPPORT_USERRESERVED',
'IPPROTO_GGP', 'IPPROTO_ICMP', 'IPPROTO_IDP', 'IPPROTO_IGMP',
'IPPROTO_IP',
'IPPROTO_MAX', 'IPPROTO_ND', 'IPPROTO_PUP', 'IPPROTO_RAW',
'IPPROTO_TCP',
'IPPROTO_UDP',
'IP_ADD_MEMBERSHIP', 'IP_DEFAULT_MULTICAST_LOOP',
'IP_DEFAULT_MULTICAST_TTL',
'IP_DROP_MEMBERSHIP', 'IP_MAX_MEMBERSHIPS', 'IP_MULTICAST_IF',
'IP_MULTICAST_LOOP',
'IP_MULTICAST_TTL', 'IP_OPTIONS', 'IP_TOS', 'IP_TTL',
'MSG_DONTROUTE',
'MSG_OOB',
'MSG_PEEK', 'NI_DGRAM', 'NI_MAXHOST', 'NI_MAXSERV', 'NI_NAMEREQD',
'NI_NOFQDN',
'NI_NUMERICHOST', 'NI_NUMERICSERV', 'SOCK_DGRAM', 'SOCK_RAW',
'SOCK_RDM',
'SOCK_SEQPACKET',
'SOCK_STREAM', 'SOL_IP', 'SOL_SOCKET', 'SOL_TCP', 'SOL_UDP',
'SOMAXCONN',
'SO_ACCEPTCONN',
'SO_BROADCAST', 'SO_DEBUG', 'SO_DONTROUTE', 'SO_ERROR',
'SO_KEEPALIVE',
'SO_LINGER',
'SO_OOBINLINE', 'SO_RCVBUF', 'SO_RCVLOWAT', 'SO_RCVTIMEO',
'SO_REUSEADDR',
'SO_SNDBUF',
'SO_SNDLOWAT', 'SO_SNDTIMEO', 'SO_TYPE', 'SO_USELOOPBACK',
'SocketType',
'TCP_NODELAY',
'__all__', '__builtins__', '__doc__', '__file__', '__name__',
'_fileobject',
'_realsocketcall', '_socket', '_socketmethods', '_socketobject',
'error',
'errorTab',
'gaierror', 'getaddrinfo', 'getfqdn', 'gethostbyaddr',
'gethostbyname',
'gethostbyname_ex',
'gethostname', 'getnameinfo', 'getprotobyname', 'getservbyname',
'herror',
'htonl',
'htons', 'inet_aton', 'inet_ntoa', 'ntohl', 'ntohs', 'socket']
It's the output on my windows machine. Lets first go through some basic calls.
Also the Python documentation has a good example of calling a Stream Socket for client and echo server.
Lets do some basic calls first.
>>>a=socket.gethostbyaddr("127.0.0.1")
>>>print a
("<nameofmyAntivirus>", [],['127.0.0.1'])
A tuple is returned, a tuple is immutable, meaining it cannot be changed like a list can. This tuple can be sliced much like a list.
For instance say we want to access the third item of this tuple, since in computer science we usually begin counting at 0, the address ["127.0.0.1"] is the 2nd item in the tuple,
thus:
>>>a[2]
['127.0.0.1']
If we wanted just the string held in this list, eg a list because of the brackets and tuple in parenthesis, we would slice again as follows.
>>>a[2][0]
'127.0.0.1'
What this does is slices the 2nd item in the tuple and the first or 0'th item of the list, since there is only 1 item at the 0'th position calling a[2][1] would return an IndexError: list index out of range.
Returning to socket operations, lets look at some other functions.
>>>a=socket.gethostname()
>>>a
mybox
//Which returns the hostname (localhostname)
>>>s.getaddrinfo("127.0.0.1", 80)
[(2, 2, 17, '', ('127.0.0.1', 80))]
Since I am running apache server, I ran getaddrinfo on port 80, getaddrinfo returns a list. The tuple inside the list is in (family, socktype, proto,flag,(host,port)) format.... What is family 2 you say or what is the 2,2,17? Well lets find out:
family is 2
socktype is 2
proto is 17
and their are no flags at this point. the host and port should be obvious. It actually took me a little while to find documentation on the protocol numbers, I don't know why... family or domain
If you have a nix flavor check: cat /etc/protocols or the RFC 1340 pages 7,8 at <a href="http://RFC.net/rfc1340.html]http://RFC.net/rfc1340.html[/url].
Either way we know that for the getaddrinfo on my windows box it returned 2 for the family, which accordingly is igmp protocol.
SockTypes
The socketype is also 2, which a decent way to find out is to use the builtin function int() as follows...
>>>int(socket.AF_INET)
2
>>>int(socket.AF_APPLETALK)
16
The family or domain for the most part ar the AF_<whatevers> so AF_INET, AF_UNIX etc... Of course if you are on a windows system, AF_UNIX will not be available.
SockTypes or Types
The Socktypes or Types are the SOCK_<whatevers> so SOCK_STREAM, SOCK_RAW, SOCK_DGRAM.
The same technique can be done with the builtin int() function to find the integer associated with a particular socktype...
>>>int(socket.SOCK_STREAM)
1
and so on.
Now that we have some of the basics of sockets down, go to python documentation and look over the socket examples provided there. It's as easy as copy and paste :) But know what you are looking at. Follow the code through, mess around with inserting you own code to send to server. Or even use the builtin funciot raw_input() to prompt the user for a message to send etc... Just use your imagination. Set some goals to achieve and figure out a way to accomplish them.
So far we have taken a dabbling into classes with a plan of attack, and then wrote a program to satisfy our goal. Sockets were then briefly gone over, because the echo server and client is done in the documentation for us I won't go over that. One should hold dear the python documentation because it is one of the most thorough I've seen for a PL besides the manpages in nix of course.... We also had a small section on slicing eg accessing an item in the tuple "127.0.0.1".
By no means is this a sequential series of tutorials, in fact it jumps around quite a bit. Instead of boring you with the syntax, I am trying to show what can be done, because as far as syntax goes, that is a trial and error/practice makes perfect kind of thing :).
In the next tutorial, we will outline a problem for some arbitray socket program. We will then come back to using classes and make a program. Then we will use the py2exe module for win32 platforms and make an executable and/or pound bang for nix flavours.
Keep it up, keep it real, cuz when it goes down, take the blue pill...
faden2u
I can be reached at:
itb2me@hotmail.com
I don't claim to know anything so... :)
This article was originally written by faden2u |