Sockets are the endpoints of a bidirectional communication channel. They may communicate within a process, between processes on the same machine or between processes on different machines. On a similar note, a network socket is one endpoint in a communication flow between two programs running over a computer network such as the Internet. It is purely a virtual thing and does not mean any hardware. Network socket can be identified by a unique combination of an IP address and port number. Network sockets may be implemented over a number of different channel types like TCP, UDP, and so on.
The different terms related to socket used in network programming are as follows −
Domain is 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 means the kind of communication between two endpoints, typically SOCK_STREAM for connection-oriented protocols and SOCK_DGRAM for connectionless protocols.
This may be used to identify a variant of a protocol within a domain and type. Its default value is 0. This is usually left out.
This works as the identifier of a network interface. A hostname nay be a string, a dotted-quad address, or an IPV6 address in colon (and possibly dot) notation.
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.
To implement socket programming in python, we need to use the Socket module. Following is a simple syntax to create a Socket −
import socket s = socket.socket (socket_family, socket_type, protocol = 0)
Here, we need to import the socket library and then make a simple socket. Following are the different parameters used while making socket −
socket_family − This is either AF_UNIX or AF_INET, as explained earlier.
socket_type − This is either SOCK_STREAM or SOCK_DGRAM.
protocol − This is usually left out, defaulting to 0.
In this section, we will learn about the different socket methods. The three different set of socket methods are described below −
In the client-server architecture, there is one centralized server that provides service and many clients receive service from that centralized server. The clients also do the request to server. A few important server socket methods in this architecture are as follows −
socket.bind() − This method binds the address (hostname, port number) to the socket.
socket.listen() − This method basically listens to the connections made to the socket. It starts TCP listener. Backlog is an argument of this method which specifies the maximum number of queued connections. Its minimum value is 0 and maximum value is 5.
socket.accept() − This will accept TCP client connection. The pair (conn, address) is the return value pair of this method. Here, conn is a new socket object used to send and receive data on the connection and address is the address bound to the socket. Before using this method, the socket.bind() and socket.listen() method must be used.
The client in the client-server architecture requests the server and receives services from the server. For this, there is only one method dedicated for clients −
socket.connect(address) − this method actively intimate server connection or in simple words this method connects the client to the server. The argument address represents the address of the server.
Other than client and server socket methods, there are some general socket methods, which are very useful in socket programming. The general socket methods are as follows −
socket.recv(bufsize) − As name implies, this method receives the TCP message from socket. The argument bufsize stands for buffer size and defines the maximum data this method can receive at any one time.
socket.send(bytes) − This method is used to send data to the socket which is connected to the remote machine. The argument bytes will gives the number of bytes sent to the socket.
socket.recvfrom(data, address) − This method receives data from the socket. Two pair (data, address) value is returned by this method. Data defines the received data and address specifies the address of socket sending the data.
socket.sendto(data, address) − As name implies, this method is used to send data from the socket. Two pair (data, address) value is returned by this method. Data defines the number of bytes sent and address specifies the address of the remote machine.
socket.close() − This method will close the socket.
socket.gethostname() − This method will return the name of the host.
socket.sendall(data) − This method sends all the data to the socket which is connected to a remote machine. It will carelessly transfers the data until an error occurs and if it happens then it uses socket.close() method to close the socket.
To establish a connection between server and client, we need to write two different Python programs, one for server and the other for client.
In this server side socket program, we will use the socket.bind() method which binds it to a specific IP address and port so that it can listen to incoming requests on that IP and port. Later, we use the socket.listen() method which puts the server into the listen mode. The number, say 4, as the argument of the socket.listen() method means that 4 connections are kept waiting if the server is busy and if a 5th socket tries to connect then the connection is refused. We will send a message to the client by using the socket.send() method. Towards the end, we use the socket.accept() and socket.close() method for initiating and closing the connection respectively. Following is a server side program −
import socket def Main(): host = socket.gethostname() port = 12345 serversocket = socket.socket() serversocket.bind((host,port)) serversocket.listen(1) print('socket is listening') while True: conn,addr = serversocket.accept() print("Got connection from %s" % str(addr)) msg = 'Connecting Established'+ "\r\n" conn.send(msg.encode('ascii')) conn.close() if __name__ == '__main__': Main()
In the client-side socket program, we need to make a socket object. Then we will connect to the port on which our server is running — 12345 in our example. After that we will establish a connection by using the socket.connect() method. Then by using the socket.recv() method, the client will receive the message from server. At last, the socket.close() method will close the client.
import socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) host = socket.gethostname() port = 12345 s.connect((host, port)) msg = s.recv(1024) s.close() print (msg.decode('ascii'))
Now, after running the server-side program we will get the following output on terminal −
socket is listening Got connection from ('192.168.43.75', 49904)
And after running the client-side program, we will get the following output on other terminal −
There are two blocks namely try and except which can be used to handle network socket exceptions. Following is a Python script for handling exception −
import socket host = "192.168.43.75" port = 12345 s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) try: s.bind((host,port)) s.settimeout(3) data, addr = s.recvfrom(1024) print ("recevied from ",addr) print ("obtained ", data) s.close() except socket.timeout : print ("No connection between client and server") s.close()
The above program generates the following output −
No connection between client and server
In the above script, first we made a socket object. This was followed by providing the host IP address and port number on which our server is running — 12345 in our example. Later, the try block is used and inside it by using the socket.bind() method, we will try to bind the IP address and port. We are using socket.settimeout() method for setting the wait time for client, in our example we are setting 3 seconds. The except block is used which will print a message if the connection will not be established between server and client.