1.Basic Socket UsagePython is using only two communication domains: UNIX(AF_UNIX) and Internet domains(AF_INET)
2.1Create Socket socket(family, type [, proto ])
family =AF_INET,AF_UNIX
type=SOCK_STREAM, SOCK_DGRAM, SOCK_RAW, SOCK_SEQPACKET,SOCK_RDM
TCP 連接語法:sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) UDP 連接語法:sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)2.2Connecting a socket and data transferInternet domain: sock.connect(('localhost', 8000))
UNIX domain:sock.connect('/tmp/sock')
2.3 Binding a name to socketInternet domain:sock.bind(('localhost', 8000))
UNIX domain:sock.bind('/tmp/sock')
2.4 Listening and accepting connectionssock.listen(5)
clisock, address = sock.accept()
TCP servers 固定流程:bind-listen-accept TCP socket is connection-oriented; when a client wants to speak to a particular server it must
connect itself, wait until the server accepts the connection, exchange data then close.
2.5 UDP sockets(保留待釐清)Data packets are send and received with the sendto(data, address ) and recvfrom(buffer[, flags ]) methods
2.6 Closing the Socketsocket.close()
記得:一定要Close a socket 才能再使用它
2.7 Socket Module 常用的function socket.getfqdn('www.yahoo.com.tw) -return the \Fully Qualied Domain Name"
>>'w2.rd.vip.tw1.yahoo.com'
>>> socket.getfqdn()
'UT09002311.uitctech.com.tw'
gethostbyname(hostname )- Get IP address
>>> socket.gethostbyname('www.yahoo.com.tw')
'119.160.246.23'
>>> socket.gethostbyname_ex('www.yahoo.com.tw')
('tw1-w2.rd.tw.g1.b.yahoo.com', ['www.yahoo.com.tw', 'rc.tpe.yahoo.com', 'tw.rc.yahoo.com', 'w2.rd.tw.g1.b.yahoo.com'], ['119.160.246.23'])
gethostbyaddr(ipaddr )-Get Host name
>>> socket.gethostbyaddr('127.0.0.1')
('localhost', [], ['127.0.0.1'])
>>> socket.gethostbyaddr('119.160.246.23')
('w2.rd.vip.tw1.yahoo.com', [], ['119.160.246.23'])
getservbyname(servname )-轉換 service 變成port
>>> socket.getservbyname('ftp')
21
getprotobyname('ICMP')- 轉換protocol 變成corresponding number
>>> socket.getprotobyname('ICMP')
1
其它:
Function Name Synopsis
htons(sint ) Convert short integer from host to network format
ntohs(sint ) Convert short integer from network to host format
htonl(lint ) Convert long integer from host to network format
ntohl(lint ) Convert long integer from network to host
3.基本網路Flow 設計TCP Model:(只能處理單一Client)
Echo server sample code:import socket
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serversocket.bind(('localhost', 8000))
serversocket.listen(1)
clientsocket, clientaddress = serversocket.accept()
print 'Connection from ', clientaddress
while 1:
data = clientsocket.recv(1024)
if not data: break
clientsocket.send(data)
clientsocket.close()
Echo client sample code:import socket
clientsocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
clientsocket.connect(('localhost', 8000))
while 1:
data = raw_input('>')
clientsocket.send(data)
if not data: break
newdata = clientsocket.recv(1024)
print newdata
clientsocket.close()
UDP Echo server sample code:# -*- Coding:Utf-8 -*-
# UDP model
from socket import *
ssock=socket(AF_INET,SOCK_DGRAM)
ssock.bind(('localhost',9999))
while 1:
data,addr =ssock.recvfrom(1024)
if not data:break
ssock.sendto(data,addr)
ssock.close()
UDP Echo client sample code:from socket import *
ssock = socket(AF_INET,SOCK_DGRAM)
while 1:
data = raw_input('>')
ssock.sendto(data, ('localhost', 9999))
if not data: break;
newdata = ssock.recvfrom(1024)
print newdata
ssock.close()
4.處理多個Client 的Server 方式:
Thread-server.py############################################################################# # Server side: open a socket on a port, listen for a message from a client, # and send an echo reply; echoes lines until eof when client closes socket; # spawns a thread to handle each client connection; threads share global # memory space with main thread; this is more portable than fork: threads # work on standard Windows systems, but process forks do not; ############################################################################# import thread, time from socket import * # get socket constructor and constants myHost = '127.0.0.1' # server machine, '' means local host myPort = 50007 # listen on a non-reserved port number sockobj = socket(AF_INET, SOCK_STREAM) # make a TCP socket object sockobj.bind((myHost, myPort)) # bind it to server port number sockobj.listen(5) # allow up to 5 pending connects def now( ): return time.ctime(time.time( )) # current time on the server def handleClient(connection): # in spawned thread: reply time.sleep(5) # simulate a blocking activity while True: # read, write a client socket data = connection.recv(1024) if not data: break connection.send('Echo=>%s at %s' % (data, now( ))) connection.close( ) def dispatcher( ): # listen until process killed while True: # wait for next connection, connection, address = sockobj.accept( ) # pass to thread for service print 'Server connected by', address, print 'at', now( ) thread.start_new(handleClient, (connection,)) dispatcher( )Class-socket.py#############################################################################
# Server side: open a socket on a port, listen for a message from a client,
# and send an echo reply; this version uses the standard library module
# SocketServer to do its work; SocketServer allows us to make a simple
# TCPServer, a ThreadingTCPServer, a ForkingTCPServer, and more, and
# routes each client connect request to a new instance of a passed-in
# request handler object's handle method; SocketServer also supports
# UDP and Unix domain sockets; see the library manual for other usage.
#############################################################################
import SocketServer, time # get socket server, handler objects
myHost = '' # server machine, '' means local host
myPort = 50007 # listen on a non-reserved port number
def now( ):
return time.ctime(time.time( ))
class MyClientHandler(SocketServer.BaseRequestHandler):
def handle(self): # on each client connect
print self.client_address, now( ) # show this client's address
time.sleep(5) # simulate a blocking activity
while True: # self.request is client socket
data = self.request.recv(1024) # read, write a client socket
if not data: break
self.request.send('Echo=>%s at %s' % (data, now( )))
self.request.close( )
# make a threaded server, listen/handle clients forever
myaddr = (myHost, myPort)
server = SocketServer.ThreadingTCPServer(myaddr, MyClientHandler)
server.serve_forever( )
Select-server.py#############################################################################
# Server: handle multiple clients in parallel with select. use the select
# module to manually multiplex among a set of sockets: main sockets which
# accept new client connections, and input sockets connected to accepted
# clients; select can take an optional 4th arg--0 to poll, n.m to wait n.m
# seconds, or ommitted to wait till any socket is ready for processing.
#############################################################################
import sys, time
from select import select
from socket import socket, AF_INET, SOCK_STREAM
def now(): return time.ctime(time.time( ))
myHost = '' # server machine, '' means local host
myPort = 50007 # listen on a non-reserved port number
if len(sys.argv) == 3: # allow host/port as cmdline args too
myHost, myPort = sys.argv[1:]
numPortSocks = 2 # number of ports for client connects
# make main sockets for accepting new client requests
mainsocks, readsocks, writesocks = [], [], []
for i in range(numPortSocks):
portsock = socket(AF_INET, SOCK_STREAM) # make a TCP/IP spocket object
portsock.bind((myHost, myPort)) # bind it to server port number
portsock.listen(5) # listen, allow 5 pending connects
mainsocks.append(portsock) # add to main list to identify
readsocks.append(portsock) # add to select inputs list
myPort += 1 # bind on consecutive ports
# event loop: listen and multiplex until server process killed
print 'select-server loop starting'
while True:
#print readsocks
readables, writeables, exceptions = select(readsocks, writesocks, [])
for sockobj in readables:
if sockobj in mainsocks: # for ready input sockets
# port socket: accept new client
newsock, address = sockobj.accept( ) # accept should not block
print 'Connect:', address, id(newsock) # newsock is a new socket
readsocks.append(newsock) # add to select list, wait
else:
# client socket: read next line
data = sockobj.recv(1024) # recv should not block
print '\tgot:', data, 'on', id(sockobj)
if not data: # if closed by the clients
sockobj.close( ) # close here and remv from
readsocks.remove(sockobj) # del list else reselected
else:
# this may block: should really select for writes too
sockobj.send('Echo=>%s at %s' % (data, now( )))