1 / 32

Chapter II

Chapter II. Reliable or Unreliable. Do you need service that keeps packets in order and guarantees delivery? Are your packets “individual” and so can arrive in any order or possibly even not at all? In the above example, you would only need to worry about non-delivery (and hence non-reply).

clyde
Download Presentation

Chapter II

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. net_py Chapter II

  2. net_py Reliable or Unreliable • Do you need service that keeps packets in order and guarantees delivery? • Are your packets “individual” and so can arrive in any order or possibly even not at all? • In the above example, you would only need to worry about non-delivery (and hence non-reply). Example: Suppose you plan to send a single packet and get a single reply?

  3. net_py UDP • Short, self-contained requests and responses. • Real-time traffic like voice. • Author says it is not used often but that is not to say it is not useful. • A single server port can receive packets from millions of distinct clients over time with no additional memory allocation beyond original setup. • congested network routers tend to be more sympathetic to UDP traffic compared to TCP traffic since they know that the latter will be retransmitted if dropped by the router. • You can add your own “99% reliability” more cheaply (performance) than using TCP's 100% reliability. • easier to use

  4. net_py Addresses and Ports running program socket memory allocation file descriptor port number UDP IP Ethernet

  5. net_py Addresses and Ports • Ports allow multiple programs to use the same TCP/IP stack • Packets come in and go up the same stack. They are “demultiplexed” at the top of the stack by port number to different programs. • The pair (IP address:port number) is called a socket and identifies a program connected to the internet, running on some machine. • Every packet sent on the internet contains a quadruplethat identifies the connection. Example: www.mysite.com:8080 (sourceIP: source port, destIP: dest port)

  6. net_py Port Ranges • Well-known: 0-1023 • Registered: 1024-4915: used by large companies • The Rest: above, used by us • How to find a well-known or registered port number • Check out the IANA (www.iana.org) >>> import socket >>> socket.getservbyname('domain')

  7. net_py Python Virtual Environment • It is a good idea to create your own virtual environment for the various python programming projects found in this course. • This gives you an easy way to install special python packages just for your own use and leave the main python install on your computer alone. • This is a useful skill for future python development you might do. • Here is an on-line tutorial; read it carefully and follow the instructions. http://dabapps.com/blog/introduction-to-pip-and-virtualenv-python/ http://virtualenvwrapper.readthedocs.org/en/latest/

  8. net_py Using virtualenvwrapper • The virtualenv tutorial suggests that inside each project directory (say Project1) there should be a project-specific virtual environment (Project1/env). • There is an alternative approach suggested by virtualenvwrapper – an extension of virtualenv. • When using using virtualenvwrapper your file hierarchy looks like: • All the executable code in .virtualenvs is from the wrapper package. Projects: ArcGIS BenchMark GeoIP Memcached QGIS Rabbit .virtualenvs: ArcGIS hook.log.1 postmkvirtualenv premkvirtualenv Benchmark initialize postrmproject prermproject BenchMarkMemcachedpostrmvirtualenv prermvirtualenv GeoIPpostactivate preactivate QGIS get_env_details postdeactivate predeactivate Rabbit hook.log postmkproject premkproject README

  9. net_py Sockets • Python makes calls to the lower level operating system-level calls that implement the networking functionality • The python interface is slightly OO • Python's contact to these OS calls is through a program construct called a socket • Sockets are “files” just like everything else and are accessed via a file descriptor, which in python you never see but in C it is all you see. • Sockets are the file descriptor • We read and write to sockets the same way we do files

  10. net_py import socket, sys s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # AF_INET is a “family” type # SOCK_DGRAM means UDP and not TCP MAX = 65535 # packet size PORT = 1060 # port used by our server if sys.argv[1:] == ['server']: # are these two lists equal s.bind(('127.0.0.1', PORT)) # specify your local socket address # since you are a server print 'Listening at', s.getsockname() # returns a list while True: data, address = s.recvfrom(MAX) # wait for traffic print 'The client at', address, 'says', repr(data) # data.toString() s.sendto('Your data was %d bytes' % len(data), address) # send reply to original sender

  11. net_py elif sys.argv[1:] == ['client']: print 'Address before sending:', s.getsockname() # 0.0.0.0:0 means no port on any interface s.sendto('This is my message', ('127.0.0.1', PORT)) print 'Address after sending', s.getsockname() # bind is automatic, but only to a port number # 0.0.0.0:34567 means port number 34567 on any interface data, address = s.recvfrom(MAX) # overly promiscuous - see Chapter 2 # will accept a datagramfrom anyone and not just the server print 'The server', address, 'says', repr(data) else: print >>sys.stderr, 'usage: udp_local.py server|client'

  12. net_py elif sys.argv[1:] == ['client']: print 'Address before bind:', s.getsockname() s.bind('',55000) print 'Address after bind:', s.getsockname() s.sendto('This is my message', ('127.0.0.1', PORT)) print 'Address after sending', s.getsockname() # bind is automatic, but only to a port number # 0.0.0.0:55000 means port number 55000 on any interface data, address = s.recvfrom(MAX) # overly promiscuous - see Chapter 2 # will accept a datagramfrom anyone and not just the server print 'The server', address, 'says', repr(data) else: print >>sys.stderr, 'usage: udp_local.py server|client'

  13. net_py Ports • Remote access to a socket is through its port number. • Access from the program that opens the socket is through the file descriptor.

  14. net_py Socket • Author says “both IP address and port number start as all zeros – a new socket is a blank slate”. This is not entirely true. • recv() vs recvfrom(): • recv(): does not return sender address and typical of client code because clients typically go to a single server and so “know” where any data they receive comes from. • recvfrom() returns sender address and is typical of server code because servers receive data from many clients and typically need to reply to a client request with a packet sent right back to the same client. The socket.sendto() function takes the address returned by recvfrom().

  15. net_py Congestion: • If you timeout and resend and the problem is that the server is down, you will add useless traffic to the network and cause congestion that will slow everyone down. • Best answer is each time you timeout extend the timeout interval so that eventually you are resending a packet only once per hour or more. • exponential backoff: delay *= 2 • What about giving up? • What about trying forever? best to give up only if you need a timely answer or not at all weather icon example

  16. net_py More Complications: • Suppose a successful request/reply exchange takes 200 ms on average. • What does the server do with duplicate requests?In both cases the server must keep track of request identifiers so it knows what requests have already been received. • If client also keeps track of request IDs and whether or not they have been replied to then the client can quietly drop duplicate replies. Client can use this information to set a minimum timeout delay to be at least 200 ms? 1) Reply again 2) Don't bother to repeat reply (How does the server know a previous reply got to the original sender?).

  17. net_py reply lost no need to pass off to higher level but must keep data ID to know it has already been forwarded optional

  18. net_py Reliable Code #!/usr/bin/env python # Foundations of Python Network Programming - Chapter 2 - udp_remote.py # UDP client and server for talking over the network import random, socket, sys s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) MAX = 65535 PORT = 1060 # usage: udp_remote.py server [ <interface> ] if 2 <= len(sys.argv) <= 3 and sys.argv[1] == 'server': # server side interface = sys.argv[2] if len(sys.argv) > 2 else '' # two single quotes s.bind((interface, PORT)) # '' is the same as '0.0.0.0' == all interfaces print 'Listening at', s.getsockname() while True: data, address = s.recvfrom(MAX) # server always needs client address if random.randint(0, 1): # flip a coin and reply only if heads print 'The client at', address, 'says:', repr(data) s.sendto('Your data was %d bytes' % len(data), address) else: # tails print 'Pretending to drop packet from', address

  19. net_py Reliable Code # Usage: udp_remote.py client <host> elif len(sys.argv) == 3 and sys.argv[1] == 'client': hostname = sys.argv[2] s.connect((hostname, PORT)) # no packets exchanged; print 'Client socket name is', s.getsockname() delay = 0.1 # initial retry delay while True: # keep resending if no reply s.send('This is another message') print 'Waiting up to', delay, 'seconds for a reply' s.settimeout(delay) # so recv() will block only so long try: data = s.recv(MAX) # blocking <delay> seconds except socket.timeout: # timeout expired delay *= 2 # double timeout delay time if delay > 2.0: # time to stop all this nonsense raise RuntimeError('I think the server is down') else: break # we are done after one success, # and can stop looping print 'The server says', repr(data)

  20. net_py Code Alternatives: • See homework

  21. net_py Connecting vs Implicit Connecting • In Listing 2-1 we used sendto(msg,address) on the client and an implicit binding happened when the first datagram was sent. • In Listing 2-2 we used send(msg) so the binding had to be done explicitly, and at the same time we indicate where the message is to be sent • In the first situation we could send to various different servers by modifying the address argument. In the latter we can only send to the address we originally connected to. s.connect(remote_host,remote_PORT) ... s.send(data) check netstat -an | grep udp at this point

  22. net_py How things look after s.sendto(msg,address): [pletcha@archimedes ~]$ python >>> import socket >>> s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM) >>> s.sendto('my message',('wyvern.cs.newpaltz.edu',50000)) 10 >>> s.getsockname() ('0.0.0.0', 52011) [pletcha@archimedes ~]$ netstat -an | grep udp udp 0 0 0.0.0.0:55188 0.0.0.0:* udp 0 0 0.0.0.0:47503 0.0.0.0:* udp 0 0 0.0.0.0:52011 0.0.0.0:* udp 0 0 0.0.0.0:60386 0.0.0.0:* udp 0 0 192.168.122.1:53 0.0.0.0:* anyone can send data to my port 52011.

  23. net_py Sneaking into the conversation [pletcha@archimedes ~]$ python >>> import socket >>> s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM) >>> s.sendto('my message',('wyvern.cs.newpaltz.edu',50000)) 10 >>> s.getsockname() ('0.0.0.0', 33897) >>> data,address = s.recvfrom(4000) >>> print data Fake reply use the bound port number as your destination [pletcha@archimedes ~]$ python >>> import socket >>> s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) >>> s.sendto('Fake reply',('127.0.0.1',33697)) 10

  24. net_py How things look after s.connect(address): > python >>> import socket >>> s =socket.socket(socket.AF_NET,socket.SOCK_DGRAM) >>> s.connect((wyvern.cs.newpaltz.edu,50000)) [pletcha@archimedes ~]$ netstat -an | grep udp udp 0 0 0.0.0.0:55188 0.0.0.0:* udp 0 0 137.140.8.104:51400 137.140.4.187:50000 ESTABLISHED udp 0 0 0.0.0.0:47503 0.0.0.0:* udp 0 0 0.0.0.0:60386 0.0.0.0:* udp 0 0 192.168.122.1:53 0.0.0.0:* no one can send data to my port 51400 except what I connected to (I really didn't connect since no data was sent)

  25. net_py Exercise • Lesson to learn: If you want to use sendto() instead of connect() followed by send(), then you can use recvfrom() and look at each sender address to be sure it is an address you recognize. • Exercise: Think of a UDP application that would have you sending data to several destinations so you could expect answers back from them all. Repeat the “sneak into the conversation” example running the client software of Listing 2-2 and see that your message never gets read by the application. It is rejected by UDP What happens is that Ethernet and IP recognize the sneaky packet as intended for this machine. IP forwards the packet to UDP. UDP looks up the destination port and sees that it will only accept data from (wyvern, 50000)

  26. net_py Request IDs • Sending a packet ID with every packet makes it easier to identify replies and know what request they are replying to. • (See homework) • Packet IDs are some protection against spoofing. Client that doesn't call connect() can be exposed to unexpected (spoofing) traffic. If the unwelcome traffic doesn't know the packet ID it is not possible to fake a response.

  27. net_py Binding to Interfaces • We have used bind() to listen on 127.0.0.1 or on ' ', which means all network interfaces. • We can specify an interface if we know its IP address (remember /sbin/ifconfig -a) • Connecting to the College using VPN I have 4 network interfaces on my laptop

  28. net_py 4 Network Interfaces at once: [pletcha@archimedes 02]$ ifconfig -a cscotun0: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST> mtu 1399 inet 137.140.108.133 netmask 255.255.255.224 destination 137.140.108.1 ... lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 ... virbr0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500 inet 192.168.122.1 netmask 255.255.255.0 broadcast 192.168.122.255 ... wlan0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 192.168.1.124 netmask 255.255.255.0 broadcast 192.168.1.255 ...

  29. net_py Ports are bound to Interfaces [pletcha@archimedes 02]$ cat all_interfaces.sh #!/usr/bin/bash ./udp_remote.py server 127.0.0.1& sleep 1; ./udp_remote.py server 137.140.108.133& sleep 1; ./udp_remote.py server 192.168.122.1& sleep 1; ./udp_remote.py server & sleep 1; ./udp_remote.py server 192.168.1.124& [pletcha@archimedes 02]$ ./all_interfaces.sh Listening at ('127.0.0.1', 1060) Listening at ('137.140.108.133', 1060) Listening at ('192.168.122.1', 1060) Traceback (most recent call last): File "./udp_remote.py", line 13, in <module> s.bind((interface, PORT)) File "/usr/lib64/python2.7/socket.py", line 224, in meth return getattr(self._sock,name)(*args) socket.error: [Errno 98] Address already in use [pletcha@archimedes 02]$ Listening at ('192.168.1.124', 1060)

  30. net_py local host vs remote host: • Local packets can arrive destined for 127.0.0.1 but they can also arrive locally by using the machine IP address, say 192.168.122.1. • By binding to 127.0.0.1, external clients can not talk to you. • By binding to 192.168.122.1 both internal and external clients can talk to you. • Lesson to Learn: Binding means specifying both a port number and a network interface (or all interfaces), so the basic data structure is not just a port but an (IP address, port) pair, in other words, a socket.

  31. net_py Two Interface problem: • Suppose a machine has two external interfaces – 192.168.122.1 and 192.168.1.124. • If we open a socket at (192.168.1.124,1060) but try to send data to (192.168.122.1, 1060) what will happen? Apparently it depends on the OS. • On my laptop I get: [pletcha@archimedes 02]$ ps -ef | grep remote pletcha 28577 3450 0 18:07 pts/1 python ./udp_remote.py server 192.168.122.1 [pletcha@archimedes 02]$ ./udp_remote.py client 192.168.1.124 Client socket name is ('192.168.1.124', 48271) Waiting up to 0.1 seconds for a reply Traceback (most recent call last): File "./udp_remote.py", line 33, in <module> data = s.recv(MAX) socket.error: [Errno 111] Connection refused

  32. net_py Fragmentation, ETC: Read the last 4 pages of Chapter 2 yourselves.

More Related