from socket import * myHost = '' # '' = all available interfaces on 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) #listen, allow 5 pending connects while True: connections, address = sockobj.accept() #wait for next client connect print 'Server connected by', address #connection is a new socket while True: data = connections.recv(1024) # read next line on client socket if not data: break # send a reply line to the client connections.send(b'Echo =>' + data) # until eof when socket closed connections.close() import sys from socket import * serverHost = 'localhost' # portable socket interface plus constants # server name, or: 'starship.python.net' serverPort = 50007 # non-reserved port used by the server message = [b'Hello network world'] # default text to send to server # requires bytes: b'' or str,encode() if len(sys.argv) > 1: serverHost = sys.argv[1] # server from cmd line arg 1 if len(sys.argv) > 2: # text from cmd line args 2..n message = (x.encode() for x in sys.argv[2:]) sockobj = socket(AF_INET, SOCK_STREAM) # make a TCP/IP socket object sockobj.connect((serverHost, serverPort)) # connect to server machine + port for line in message: sockobj.send(line) # send line to server over socket data = sockobj.recv(1024) # receive line from server: up to 1k print 'Client received:', data # bytes are quoted, was `x`, repr(x) sockobj.close() sockobj = socket(AF_INET, SOCK_STREAM) sockobj.bind((myHost, myPort)) sockobj.listen(5) connection, address = sockobj.accept() data = connection.recv(1024) connection.send(b'Echo=>' + data) import pickle x = pickle.dumps([99,100]) # on sending end... convert to byte strings x # string passed to send, returned by recv pickle.loads(x) # on receiving end... convert back to object import struct x = struct.pack('>ii', 99 ,100) # convert simpler types for transmission x struct.unpack('>ii',x) sockobj.connect((serverHost, serverPort)) sockobj.send(line) !ping learning-python.com import sys from PP4E.launchmodes import QuietPortableLauncher numclients = 8 def start(cmdline): QuietPortableLauncher(cmdline, cmdline)() # start('echo-server.py') # spawn server locally if not yet started args = ' '.join(sys.argv[1:]) # pass server name if running remotely for i in range(numclients): start('echo-client.py %s' % args) # spawn 8? clients to test the server from socket import * sock = socket(AF_INET,SOCK_STREAM) sock.connect(('pop.secureserver.net', 110)) print sock.recv(70) sock.close() sock = socket(AF_INET,SOCK_STREAM) sock.connect(('learning-python.com', 21)) print sock.recv(70) sock.close() sock = socket(AF_INET,SOCK_STREAM) sock.connect(('www.python.net', 80)) sock.send(b'GET /\r\n') # fetch root page reply sock.recv(70) sock.recv(70) sock.close() sock = socket(AF_INET,SOCK_STREAM) sock.bind(('',80)) import os, time, sys from socket import * myHost = '' # '' = all available interfaces on 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) #listen, allow 5 pending connects def now(): return time.ctime(time.time()) activeChildren = [] def reapChildren(): # reap any dead child processes while activeChildren: # else may fill up system table pid, stat = os.waitpid(0, os.WNOHANG) # don't hang if no child exited if not pid: break activeChildren.remove(pid) # child process: reply, exit simulate a blocking activity # read, write a client socket till eof when socket closed def handleClient(connection): time.sleep(5) while True: data = connections.recv(1024) # read next line on client socket if not data: break # send a reply line to the client reply = 'Echo=>%s at %s' % (data,now()) connections.send(reply.encode()) # until eof when socket closed connections.close() os._exit(0) def dispatcher(): # listen until process killed while True: # wait for next connection, connection, address = sockobj.accept() # pass to process for service print 'Server connected by', address, 'at', now() reapChildren() # clean up exited children now childPid = os.fork() # copy this process if childPid == 0: # if in child process: handle handleClient(connection) else: # else: go accept next connect activeChildren.append(childPid) # add to active child pid list dispatcher() !netstat -pant | grep 50007 #show 50007 port !kill -9 pid # kill python server # Demo Python's signal module; pass signal number as a command-line arg, and use # a "kill -N pid" shell command to send this process a signal; on my Linux machine, # SIGUSR1=10, SIGUSR2=12, SIGCHLD=17, and SIGCHLD handler stays in effect even if # not restored: all other handlers are restored by Python after caught, but SIGCHLD # behavior is left to the platform's implementation; signal works on Windows too, # but defines only a few signal types; signals are not very portable in general import sys, signal, time def now(): return time.asctime() def onSignal(signum, stackframe): # Python signal handler print 'Got signal', signum, 'at', now() # most handlers stay in effect but sigchld handler is not if signum == signal.SIGCHLD: #signal.signal(signal.SIGCHLD, onSignal) print 'sigchld caught' signum = int(sys.argv[1]) signal.signal(signum, onSignal) # install signal handler while True: signal.pause() # sleep waiting for signals import os, time, sys from socket import * myHost = '' # '' = all available interfaces on 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) #listen, allow 5 pending connects signal.signal(signal.SIGCHLD, signal.SIG_IGN) #avoid child zombie processes def now(): return time.ctime(time.time()) # child process: reply, exit simulate a blocking activity # read, write a client socket till eof when socket closed def handleClient(connection): time.sleep(5) while True: data = connections.recv(1024) # read next line on client socket if not data: break # send a reply line to the client reply = 'Echo=>%s at %s' % (data,now()) connections.send(reply.encode()) # until eof when socket closed connections.close() os._exit(0) def dispatcher(): # listen until process killed while True: # wait for next connection, connection, address = sockobj.accept() # pass to process for service print 'Server connected by', address, 'at', now() childPid = os.fork() # copy this process if childPid == 0: # if in child process: handle handleClient(connection) # 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 time, _thread as thread # or use threading.Thread().start() from socket import * # get socket constructor and constants myHost = '' # 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 reply = 'Echo=>%s at %s' % (data, now()) connection.send(reply.encode()) 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, 'at', now() thread.start_new_thread(handleClient, (connection,)) dispatcher() """ 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 provides TCPServer, ThreadingTCPServer, ForkingTCPServer, UDP variants of these, 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 Unix domain sockets, but only on Unixen; see the Python library manual. """ import SocketServer as 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 reply = 'Echo=>%s at %s' % (data, now()) self.request.send(reply.encode()) self.request.close() # make a threaded server, listen/handle clients forever myaddr = (myHost, myPort) server = socketserver.ThreadingTCPServer(myaddr, MyClientHandler) server.serve_forever() # P822 """ 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 omitted to wait till any socket is ready for processing. """ import sys import 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 socket 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 reply = 'Echo=>%s at %s' % (data, now()) sockobj.send(reply.encode()) # socket-unbuff-server.py from __future__ import print_function from socket import * # read three messages over a raw socket sock = socket() sock.bind(('', 60000)) sock.listen(5) print('accepting...') conn, id = sock.accept() # blocks till client connect for i in range(3): print('receiving...') msg = conn.recv(1024) # blocks till data received print(msg) # gets all print lines at once unless flushed # socket-unbuff-client.py # send three msgs over wrapped and raw socket from __future__ import print_function import time from socket import * sock = socket() # default=AF_INET, SOCK_STREAM (tcp/ip) sock.connect(('localhost', 60000)) # default=full buff, 0=error, 1 not linebuff! file = sock.makefile('w', buffering=1) print('sending data1') file.write('spam\n') time.sleep(5) # must follow with flush() to truly send now # file.flush() # uncomment flush lines to see the difference print('sending data2') # adding more file prints does not flush buffer either print('eggs', file) time.sleep(5) # file.flush() # output appears at server recv only upon # flush or exit print('sending data3') sock.send(b'ham\n') # low-level byte string interface sends immediately time.sleep(5) # received first if don't flush other two! # pipe-unbuff-writer.py # output line buffered (unbuffered) if stdout is a terminal, buffered by default for # other devices: use -u or sys.stdout.flush() to avoid delayed output on pipe/socket import time, sys for i in range(5): print(time.asctime()) # print transfers per stream buffering sys.stdout.write('spam\n') # ditto for direct stream file access time.sleep(2) # unles sys.stdout reset to other file # no output for 10 seconds unless Python -u flag used or sys.stdout.flush() # but writer's output appears here every 2 seconds when either option is used from __future__ import print_function import os for line in os.popen('python -u pipe-unbuff-writer.py'): # iterator reads lines print(line, end='') # blocks without -u! """ ############################################################################# implement client and server-side logic to transfer an arbitrary file from server to client over a socket; uses a simple control-info protocol rather than separate sockets for control and data (as in ftp), dispatches each client request to a handler thread, and loops to transfer the entire file by blocks; see ftplib examples for a higher-level transport scheme; ############################################################################# """ import sys, os, time, thread from socket import * blksz = 1024 defaultHost = 'localhost' defaultPort = 50001 helptext = """ Usage... server=> getfile.py -mode server [-port nnn] [-host hhh|localhost] client=> getfile.py [-mode client] -file fff [-port nnn] [-host hhh|localhost] """ def now(): return time.asctime() def parsecommandline(): dict = {} # put in dictionary for easy lookup args = sys.argv[1:] # skip program name at front of args while len(args) >= 2: # example: dict['-mode'] = 'server' dict[args[0]] = args[1] args = args[2:] return dict def client(host, port, filename): sock = socket(AF_INET, SOCK_STREAM) sock.connect((host, port)) sock.send((filename + '\n').encode()) # send remote name with dir: bytes dropdir = os.path.split(filename)[1] # filename at end of dir path file = open(dropdir, 'wb') # create local file in cwd while True: data = sock.recv(blksz) # get up to 1K at a time if not data: break # till closed on server side file.write(data) # store data in local file sock.close() file.close() print('Client got', filename, 'at', now()) def serverthread(clientsock): sockfile = clientsock.makefile('r') # wrap socket in dup file obj filename = sockfile.readline()[:-1] # get filename up to end-line try: file = open(filename, 'rb') while True: bytes = file.read(blksz) # read/send 1K at a time if not bytes: break # until file totally sent sent = clientsock.send(bytes) assert sent == len(bytes) except: print 'Error downloading file on server:', filename clientsock.close() def server(host, port): serversock = socket(AF_INET, SOCK_STREAM) # listen on TCP/IP socket serversock.bind((host, port)) # serve clients in threads serversock.listen(5) while True: clientsock, clientaddr = serversock.accept() print 'Server connected by', clientaddr, 'at', now() thread.start_new_thread(serverthread, (clientsock,)) def main(args): host = args.get('-host', defaultHost) # use args or defaults port = int(args.get('-port', defaultPort)) # is a string in argv if args.get('-mode') == 'server': # None if no -mode: client if host == 'localhost': host = '' # else fails remotely server(host, port) elif args.get('-file'): # client mode needs -file client(host, port, args['-file']) else: print helptext if __name__ == '__main__': args = parsecommandline() main(args) """ launch getfile script client from simple tkinter GUI; could also use os.fork+exec, os.spawnv (see Launcher); windows: replace 'python' with 'start' if not on path; """ import os from tkinter import * from tkinter.messagebox import showinfo def onReturnKey(): cmdline = ('python getfile.py -mode client -file %s -port %s -host %s' % (content['File'].get(), content['Port'].get(), content['Server'].get())) os.system(cmdline) showinfo('getfilegui-1', 'Download complete') box = Tk() labels = ['Server', 'Port', 'File'] content = {} for label in labels: row = Frame(box) row.pack(fill=X) Label(row, text=label, width=6).pack(side=LEFT) entry = Entry(row) entry.pack(side=RIGHT, expand=YES, fill=X) content[label] = entry box.title('getfilegui-1') box.bind('', (lambda event: onReturnKey())) mainloop() """ same, but with grids and import+call, not packs and cmdline; direct function calls are usually faster than running files; """ import getfile from tkinter import * from tkinter.messagebox import showinfo def onSubmit(): getfile.client(content['Server'].get(), int(content['Port'].get()), content['File'].get()) showinfo('getfilegui-2', 'Download complete') box = Tk() labels = ['Server', 'Port', 'File'] rownum = 0 content = {} for label in labels: Label(box, text=label).grid(column=0, row=rownum) entry = Entry(box) entry.grid(column=1, row=rownum, sticky=E+W) content[label] = entry rownum += 1 box.columnconfigure(0, weight=0) # make expandable box.columnconfigure(1, weight=1) Button(text='Submit', command=onSubmit).grid(row=rownum, column=0, columnspan=2) box.title('getfilegui-2') box.bind('', (lambda event: onSubmit())) mainloop() """ ################################################################## a reusable form class, used by getfilegui (and others) ################################################################## """ from tkinter import * entrysize = 40 class Form: # add non-modal form box def __init__(self, labels, parent=None): # pass field labels list labelsize = max(len(x) for x in labels) + 2 box = Frame(parent) # box has rows, buttons box.pack(expand=YES, fill=X) # rows has row frames rows = Frame(box, bd=2, relief=GROOVE) # go=button or return key rows.pack(side=TOP, expand=YES, fill=X) # runs onSubmit method self.content = {} for label in labels: row = Frame(rows) row.pack(fill=X) Label(row, text=label, width=labelsize).pack(side=LEFT) entry = Entry(row, width=entrysize) entry.pack(side=RIGHT, expand=YES, fill=X) self.content[label] = entry Button(box, text='Cancel', command=self.onCancel).pack(side=RIGHT) Button(box, text='Submit', command=self.onSubmit).pack(side=RIGHT) box.master.bind('', (lambda event: self.onSubmit())) def onSubmit(self): # override this for key in self.content: # user inputs in print(key, '\t=>\t', self.content[key].get()) # self.content[k] def onCancel(self): # override if need Tk().quit() # default is exit class DynamicForm(Form): def __init__(self, labels=None): labels = input('Enter field names: ').split() Form.__init__(self, labels) def onSubmit(self): print('Field values...') Form.onSubmit(self) self.onCancel() if __name__ == '__main__': import sys if len(sys.argv) == 1: Form(['Name', 'Age', 'Job']) # precoded fields, stay after submit else: DynamicForm() # input fields, go away after submit mainloop() """ launch getfile client with a reusable GUI form class; os.chdir to target local dir if input (getfile stores in cwd); to do: use threads, show download status and getfile prints; """ from form import Form from tkinter import Tk, mainloop from tkinter.messagebox import showinfo import getfile, os class GetfileForm(Form): def __init__(self, oneshot=False): root = Tk() root.title('getfilegui') labels = ['Server Name', 'Port Number', 'File Name', 'Local Dir?'] Form.__init__(self, labels, root) self.oneshot = oneshot def onSubmit(self): Form.onSubmit(self) localdir = self.content['Local Dir?'].get() portnumber = self.content['Port Number'].get() servername = self.content['Server Name'].get() filename = self.content['File Name'].get() if localdir: os.chdir(localdir) portnumber = int(portnumber) getfile.client(servername, portnumber, filename) showinfo('getfilegui', 'Download complete') if self.oneshot: Tk().quit() # else stay in last localdir if __name__ == '__main__': GetfileForm() mainloop()