You are on page 1of 22

26/02/2024

 

GV: Nguyễn Thị Thanh Vân - CNTT

socket() socket()

bind() bind()

recvfrom() sendto()

[blocked] recvfrom()

[blocked]
sendto()

SERVER CLIENT

1
26/02/2024

socket() Server Client


bind()
socket()

listen()
connect()

accept()
write()
[blocked]
read()

read() [blocked]

[blocked]

write()
When interaction is over, server
loops to accept a new connection

 Passive participant  Active participant


o step 1: listen (for o step 2: request & establish
incoming requests) connection
o step 3: accept (a request)
o step 4: data transfer o step 4: data transfer

Passive Participant
 The accepted
connection is on a new a-sock-1 l-sock a-sock-2
socket
 The old socket
continues to listen for
other active participants socket socket
Active 1 Active 2
4

2
26/02/2024

Python's socket module has


o class-based utilities – SocketServer module
o instances-based utilities – Socket Object

 Socket lib
o from socket import socket

 Family address
 Socket Types
 Server Libraries

3
26/02/2024

Term Term & Description


domain The family of protocols that is used as the transport mechanism. These values
are constants such as AF_INET, PF_INET, PF_UNIX, PF_X25, and so on.
type The type of communications between the two endpoints, typically
SOCK_STREAM for connection-oriented protocols and SOCK_DGRAM for
connectionless protocols.
protocol Typically zero, this may be used to identify a variant of a protocol within a
domain and type.
hostname The identifier of a network interface −
•A string, which can be a host name, a dotted-quad address, or an IPV6 address
in colon (and possibly dot) notation
•A string "<broadcast>", which specifies an INADDR_BROADCAST address.
•A zero-length string, which specifies INADDR_ANY, or
•An Integer, interpreted as a binary address in host byte order.
port Each server listens for clients calling on one or more ports. A port may be a
Fixnum port number, a string containing a port number, or the name of a
service.

Address Families Socket Types

 socket.AF_UNIX  socket.SOCK_STREAM
o Unix named pipe (NOT o TCP, connection-oriented
Windows…)  socket.SOCK_DGRAM
 socket.AF_INET o UDP, connectionless
o Internet – IP version 4  socket.SOCK_RAW
o The basis of this class
o Gives access to subnetwork layer
 socket.AF_INET6
 SOCK_RDM,
o Internet – IP version 6 SOCK_SEQPACKET
o Rather more complicated … o Very rarely used

4
26/02/2024

 Can set a default for all sockets


o socket.setdefaulttimeout(seconds)
o Argument is float # of seconds

o Or None (indicates no timeout)

 Can set a timeout on an existing socket s


o s.settimeout(seconds)

 To create a socket, you must use the socket.socket() function


available in the socket module, which has the general syntax −

s=socket.socket (socket_family, socket_type, protocol = 0)

The description of the parameters −


o socket_family − AF_UNIX or AF_INET,
o socket_type − SOCK_STREAM or SOCK_DGRAM.
o protocol − This is usually left out, defaulting to 0.
 Once you have socket object, then you can use the required
functions to create your client or server program. Following is the
list of functions required

5
26/02/2024

S = socket.socket (socket_family, socket_type, protocol = 0)

Method Description
Server Socket
s.bind() This method binds address (hostname, port number
pair) to socket.
s.listen() This method sets up and start TCP listener.
s.accept() This passively accept TCP client connection, waiting
until connection arrives (blocking).
Client Socket
s.connect() This method actively initiates TCP server connection.

Method Description
s.recv() This method receives TCP message
s.send() This method transmits TCP message
s.recvfrom() This method receives UDP message
s.sendto() This method transmits UDP message
s.close() This method closes socket
socket.gethostname() Returns the hostname.

6
26/02/2024

from socket import socket, AF_INET, SOCK_DGRAM


s = socket(AF_INET, SOCK_DGRAM)
s.bind(('127.0.0.1', 11111))
while True:
data, addr = s.recvfrom(1024) Empty -> all
print "Connection from", addr
s.sendto(data.upper(), addr)

Note that the bind() argument is a two-element tuple of address and port
number.
Server can reply multi request from client
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

from socket import socket, AF_INET, SOCK_DGRAM


s = socket(AF_INET, SOCK_DGRAM)
s.bind(('127.0.0.1', 0)) # OS chooses port
print "using", s.getsocketname()
server = ('127.0.0.1', 11111)
s.sendto("MixedCaseString", server)
data, addr = s.recvfrom(1024)
print "received", data, "from", addr
s.close()

7
26/02/2024

from socket import socket, AF_INET, SOCK_STREAM


BUFFER_SIZE = 30 # Normally 1024, but we want fast response
s = socket(AF_INET, SOCK_STREAM) # Create TCP socket
s.bind(("",8888)) # Bind to port 8888
s.listen(5) # Start listening
print ("Server is listening")
conn, addr =s.accept()
while 1:
data = conn.recv(BUFFER_SIZE)
if not data: break
print ("received data:", data)
conn.send(data.upper()) # echo
conn.close()

from socket import *


BUFFER_SIZE = 1024
s = socket(AF_INET,SOCK_STREAM) # Create TCP socket
s.connect(("127.0.0.1",8888)) # Connect to server
print ("Hello, I am using", s.getsockname())
while 1:
msg = input('Enter message to send : ')
s.send(msg.encode('utf-8'))
data = s.recv(BUFFER_SIZE)
print ("received data:", data, "from server ")
if msg == 'Q':
print("Quit now...")
break
s.close()
ConnectionRefusedError: [WinError 10061] No connection could
be made because the target machine actively refused it

8
26/02/2024

 SocketServer: A framework for network servers.


Provides:
o Subclass the TCPServer to serve TCP
class socketserver.TCPServer(server_address, RequestHandlerClass
, bind_and_activate=True)
o Subclass the UDPServer to serve UDP
class socketserver.UDPServer(server_address, RequestHandlerClass
, bind_and_activate=True)
 In Unix domain sockets:
class socketserver.UnixStreamServer(server_address, RequestHandl
erClass, bind_and_activate=True)
class socketserver.UnixDatagramServer(server_address, RequestHan
dlerClass, bind_and_activate=True)

 Creating a server requires several steps:


o 1. create a request handler class by subclassing
the BaseRequestHandler class and overriding its handle() method;
this method will process incoming requests.
o 2. instantiate one of the server classes, passing it the server’s
address and the request handler class.
o 3. call the handle_request() or serve_forever() method of the
server object to process one or many requests.

9
26/02/2024

import socketserver
class MyTCPHandler(socketserver.BaseRequestHandler):
def handle(self):
# self.request is the TCP socket connected to the client
self.data = self.request.recv(1024).strip()
print("{} wrote:".format(self.client_address[0]))
print(self.data)
# just send back the same data, but upper-cased
self.request.sendall(self.data.upper())

if __name__ == "__main__":
HOST, PORT = "localhost", 9999
# Create the server, binding to localhost on port 9999
with socketserver.TCPServer((HOST, PORT), MyTCPHandler) as server:
# keep running until interrupting the program
server.serve_forever()
class MyTCPHandler(socketserver.StreamRequestHandler):
def handle(self):
self.data = self.rfile.readline().strip()
print("{} wrote:".format(self.client_address[0]))
print(self.data)
self.wfile.write(self.data.upper())

import socket
import sys
HOST, PORT = "localhost", 9999
while 1:
#data = " ".join(sys.argv[1:])
data = input('Enter message to send : ')

# Create a socket (SOCK_STREAM means a TCP socket)


with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
# Connect to server and send data
sock.connect((HOST, PORT))
sock.sendall(bytes(data + "\n", "utf-8"))

# Receive data from the server and shut down


received = str(sock.recv(1024), "utf-8")
print("Sent: {}".format(data))
print("Received: {}".format(received))
if data == 'Q':
print("Quit now...")
break

10
26/02/2024

 Mix-in classes allow asynchronous handling via Two class:


o class socketserver.ForkingMixIn
o class socketserver.ThreadingMixIn
 add the ability to handle each request in a separate thread or
a separate process

 Serverinstance created with address and handler-class as


arguments:
SocketServer.UDPServer(myaddr, MyHandler)
 Each connection/transmission creates a request handler instance
by calling the handler-class*
 Created handler instance handles a message (UDP) or a
complete client session (TCP)
* In Python you instantiate a class by calling it like a function

11
26/02/2024

 There are two different kind of threads −


o kernel thread
o user thread
Kernel Threads are a part of the operating system, while the User-space
threads are not implemented in the kernel.
 There are two modules which support the usage of threads in
Python3
o _thread
o threading
 The thread module has been "deprecated" for quite a long time.

 Tospawn another thread, you need to call following method


available in _thread module:
_thread.start_new_thread(function, args[, kwargs])
 This method call enables a fast and efficient way to create new
threads in both Linux and Windows.
 The method call returns immediately and the child thread starts
and calls function with the passed list of args. When function
returns, the thread terminates.
 Here, args is a tuple of arguments; use an empty tuple to call
function without passing any arguments. kwargs is an optional
dictionary of keyword arguments.

12
26/02/2024

import _thread
import time
# Define a function for the thread
def print_time( threadName, delay):
count = 0
while count < 5:
time.sleep(delay)
count += 1
print ("%s: %s" % ( threadName, time.ctime(time.time()) ))
# Create two threads as follows
try:
_thread.start_new_thread( print_time, ("Thread-1", 2, ) )
_thread.start_new_thread( print_time, ("Thread-2", 4, ) )
except:
print ("Error: unable to start thread")
while 1:
pass

Thread-1: Mon Oct 1 11:46:06 2018


Thread-2: Mon Oct 1 11:46:08 2018
Thread-1: Mon Oct 1 11:46:08 2018
Thread-1: Mon Oct 1 11:46:10 2018
Thread-2: Mon Oct 1 11:46:12 2018
Thread-1: Mon Oct 1 11:46:12 2018
Thread-1: Mon Oct 1 11:46:14 2018
Thread-2: Mon Oct 1 11:46:16 2018
Thread-2: Mon Oct 1 11:46:20 2018
Thread-2: Mon Oct 1 11:46:24 2018
Although it is very effective for low-level threading, but the thread
module is very limited compared to the newer threading module.

13
26/02/2024

A thread remains inactive until start method runs


o Thread is placed in the ready queue
o Newly started thread’s run method is also activated
A thread can lose access to the CPU:
o Time-out (process also known as time slicing)
o Sleep
o Block
o Wait
Process of saving/restoring a thread’s state is
called a context switch

14
26/02/2024

 Thethreading module exposes all the methods of the thread


module and provides some additional methods:
o threading.activeCount():
Returns the number of thread objects that are active.
o threading.currentThread():
Returns the number of thread objects in the caller's thread control.
o threading.enumerate():
Returns a list of all thread objects that are currently active.

 The threading module has the Thread class that implements


threading.
 The methods provided by the Thread class are as follows:
o run(): The run() method is the entry point for a thread.
o start(): The start() method starts a thread by calling the run method.
o join([time]): The join() waits for threads to terminate.
o isAlive(): The isAlive() method checks whether a thread is still executing.
o getName(): The getName() method returns the name of a thread.
o setName(): The setName() method sets the name of a thread.

15
26/02/2024

 To implement a new thread using the threading module, you have


to do the following −
o Define a new subclass of the Thread class.
o Override the __init__(self [,args]) method to add additional arguments.
o Then, override the run(self [,args]) method to implement what the thread
should do when started.
 Operation:
o Once you have created the new Thread subclass, you can create an
instance of it
o Then start a new thread by invoking the start(), which in turn calls run()
method.

import threading Module threading provides multithreading capabilities


import time
Thread class derived from base class threading.Thread
exitFlag = 0
class myThread (threading.Thread): Instantiate PrintThread object

def __init__(self, threadID, name, counter):


threading.Thread.__init__(self)
# Create new threads
self.threadID = threadID thd1 = myThread(1, "Thread-1", 1)
self.name = name thd2 = myThread(2, "Thread-2", 2)
self.counter = counter # Start new Threads
def run(self): Overridden Thread run method
thd1.start()
print ("Starting " + self.name) thd2.start()
print_time(self.name, self.counter, 5) thd1.join()
print ("Exiting " + self.name) thd2.join()
print ("Exiting Main Thread")
def print_time(threadName, delay, counter):
while counter:
if exitFlag:
threadName.exit()
time.sleep(delay)
print ("%s: %s" % (threadName, time.ctime(time.time())))
counter -= 1

16
26/02/2024

Starting Thread-1
Starting Thread-2
Thread-1: Mon Oct 1 15:02:36 2018
Thread-2: Mon Oct 1 15:02:37 2018
Thread-1: Mon Oct 1 15:02:37 2018
Thread-1: Mon Oct 1 15:02:38 2018
Thread-2: Mon Oct 1 15:02:39 2018
Thread-1: Mon Oct 1 15:02:39 2018
Thread-1: Mon Oct 1 15:02:40 2018
Exiting Thread-1
Thread-2: Mon Oct 1 15:02:41 2018
Thread-2: Mon Oct 1 15:02:43 2018
Thread-2: Mon Oct 1 15:02:45 2018
Exiting Thread-2
Exiting Main Thread

# Create new threads array


numThr = 3
print('Creating ', numThr, 'threads \n')
worker = list()
for i in range(numThr):
n="Thread_" + str(i)
worker.append(myThread(i, n, i))
worker[i].start()
worker[i].join()
print('Threads have been created and started \n')

17
26/02/2024

 Mỗi Thread tạo ra đều thực thi các tác vụ giống nhau (theo run())
 Muốn mỗi Thread thực hiện một tác vụ khác nhau?
o Tạo các method riêng cho các thread
o Tạo constructor, giá trị truyền vào khác nhau
o Tạo các thread ở các class khác nhau, viết run() riêng cho mỗi thread.

35

MultiThreads:
Các tuyến đoạn có thể truy xuất tới tài
nguyên dùng chung để cùng làm việc
hợp tác với nhau.
Nảy sinh vấn đề gì?

36

18
26/02/2024

The single expression can be


o Retrieve the current value of c.
o Increment the retrieved value by 1.
o Store the incremented value back in c.

Ex, Thread A invokes increment at about the same


time Thread B invokes decrement. If the initial value of
c is 0,
o Thread A: Retrieve c.
o Thread B: Retrieve c.
o Thread A: Increment retrieved value; result is 1.
o Thread B: Decrement retrieved value; result is -1.
o Thread A: Store result in c; c is now 1.
37
o Thread B: Store result in c; c is now -1.

 The threading module provided with Python includes a simple-to-


implement locking mechanism that allows you to synchronize
threads.
 A new lock is created by calling the Lock() method, which returns
the new lock.
 The acquire(blocking) method of the new lock object is used to
force threads to run synchronously.
o The optional blocking parameter enables you to control whether the
thread waits to acquire the lock.

19
26/02/2024

 If blocking is set to 0, the thread returns immediately with a 0


value if the lock cannot be acquired and with a 1 if the lock was
acquired.
 If blocking is set to 1, the thread blocks and wait for the lock to be
released.
 The release() method of the new lock object is used to release the
lock when it is no longer required.

import threading
import time

class myThread (threading.Thread):


def __init__(self, threadID, name, counter):
threading.Thread.__init__(self)
self.threadID = threadID
self.name = name
self.counter = counter
def run(self):
print ("Starting " + self.name)
# Get lock to synchronize threads
threadLock.acquire()
print_time(self.name, self.counter, 3)
# Free lock to release next thread
threadLock.release()

def print_time(threadName, delay, counter):


while counter:
time.sleep(delay)
print ("%s: %s" % (threadName, time.ctime(time.time())))
counter -= 1

20
26/02/2024

threadLock = threading.Lock()
threads = []
# Create new threads
thread1 = myThread(1, "Thread-1", 1)
thread2 = myThread(2, "Thread-2", 2)

# Start new Threads


thread1.start()
thread2.start()

# Add threads to thread list


threads.append(thread1)
threads.append(thread2)

# Wait for all threads to complete


for t in threads:
t.join()
print ("Exiting Main Thread")

Starting Thread-1
Starting Thread-2
Thread-1: Mon Oct 1 15:30:55 2018
Thread-1: Mon Oct 1 15:30:56 2018
Thread-1: Mon Oct 1 15:30:57 2018
Thread-2: Mon Oct 1 15:30:59 2018
Thread-2: Mon Oct 1 15:31:01 2018
Thread-2: Mon Oct 1 15:31:03 2018
Exiting Main Thread

21
26/02/2024

 Socket
 Multithread

22

You might also like