Connect Two Computers Using Secure Socket Programming in Python

Connect Two Computers Using Secure Socket Programming in Python

Nowadays the Internet has grown to be a ‘Soul of Living’ and its actions are characterized by ‘networks’ or ‘’connections. These networks work by utilizing one of the most essential fundamentals of sockets. This article will cover different sections like how to deal with socket programming in Python, how sockets help you make certain connections, while Python, surely, makes it simple.

Sockets and the socket API provide a form of inter-process communication (IPC) and are used to send messages across a network. The network can be a local network to the computer, a logical network, or the one that is physically connected to an external network, including its connections to other networks. The simple example you can consider here is the Internet, which you connect to through your ISP (Internet Service Provider).

What is Socket Programming?

Secure socket programming in python can be defined as a program that allows two sockets to transmit and collect data, at any given moment, bi-directionally. It operates by combining two nodes or sockets and enabling them to communicate in real-time, it is an excellent option for creating a myriad of apps.

Why Use Sockets to Transmit Data?

Applications that require an internet connection to work in real-time greatly benefit from the implementation of sockets within their networking code. Some instances of these types of apps that utilize socket programming are web pages that have live notifications like eBay, Facebook, multiplayer online games like Counter-Strike, League of Legends, and other chatting apps like WeChat, WhatsApp, etc.

Unlike web development language JavaScript, Python is a language that executes synchronously. Here data can be sent or received at any time with the use of streaming sockets. Now if your Python program is in the middle of implementing some code, other threads can manage the new socket data. Libraries like asyncio execute multiple threads, to make your Python program work asynchronously.

Connecting Two Computers Over Different Networks Using Sockets

The server generates the listener socket while the client reaches out to the server. They are the actual backbones behind web browsing. In more simplistic terms, there is a client and a server. You can begin Socket programming in python by importing the socket library and creating a simple socket.

For example:

import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

Above is a socket instance with two parameters, the primary parameter is AF_INET and the secondary one is SOCK_STREAM. Now you can connect to a server utilizing this socket.

You need to use a functional server-client program to connect two computers on an identical network and transfer data between them. The server receives the data transmitted from one laptop and transfers it to another. Both clients hold the IP address of the server.

These steps are involved to use sockets to connect two computers using socket programming in python:

Step 1) Create a Socket

A socket, s, is created by the socket system call:

ints = socket(domain, type, protocol)

All the parameters, and the return value, are integers: domain, or approach family – communication domain under which the socket is created. Some of the address families are AF UNIX, AF INET (IP), AF INET6 (IPv6), AF NS, and AF ISO (ISO protocols) type of service. This is chosen as per the properties needed by the application: SOCK DGRAM (datagram service), SOCK STREAM (virtual circuit service), SOCK RAW (direct IP service).

Verify with your address family to check whether a particular service is available. You can understand this way that creating a socket is like requesting a telephone line from the phone company.

For TCP/IP sockets, we want to define the virtual circuit service (SOCK STREAM) and the IP address family (AF INET). Code for creating a TCP socket looks like this:

#include <sys/socket.h>

if ((fd = socket(AF INET, SOCK STREAM, 0)) <0)

{ perror(”cannot create socket”); return 0; }

Step 2) Identify a Socket 

When we consider naming a socket, it is like assigning a transport address to the socket i.e. a port number in IP networking. Under sockets, this operation is termed binding an address using a bind system call. The transport address is specified within a socket address structure. Because sockets are designed to work with several kinds of communication interfaces. For example, if you are utilizing UNIX domain sockets, bind generates a file in the file system.

The system call for bind is:

#include <sys/socket.h>

int bind(int socket, const struct sockaddr *address, socklen t address len);

If you are a client that won’t get incoming connections, you can let the operating system choose any possible port number by defining port 0. If you are a server, you will choose a specific number as clients will need to understand a port number to connect to. sin aaddr.

With IP, your machine will have a single IP address for every network interface. Moreover, the address structure may vary based on the type of transport used.

Step 3) Connect to a Server from a Client

For a client process, you need to establish a connection to the server. Currently, as defined above we are having a socket that knows where it is coming from, so we need to tell it where it’s going. The connect system call achieves this.

#include <sys/types.h>

#include <sys/socket.h>

int connect(int socket, const struct sockaddr *address, socklen t address len);

The primary parameter, socket, is the socket that was created with the socket system call and named through bind. The secondary parameter identifies the remote-transport address using the same sockaddr. With bind, a third parameter is just the length of the structure within the second parameter: sizeof(struct sockaddr in).

The server’s address will include the port number and the IP address of the server machine that corresponds to a socket listening on that port on that machine. A simple method of obtaining the IP address is by the gethostbyname library (libc) function. Gethostbyname accepts a host name as a parameter and returns a hostent.

Step 4) Accept Connections on the Server

Before a client connects to a server, the server should own a socket that can accept the connections. The listen to system call reports a socket that should be able to accept incoming connections:

#include <sys/socket.h>

int listen(int socket, int backlog);

The secondary parameter, backlog, represents the maximum number of pending connections that can be queued up before connections are denied. The accept system call grasps the first connection request on the queue of pending connections and builds a new socket for that connection.

The syntax of accept is:

#include <sys/socket.h>

int accept(int socket, struct sockaddr *restrict address, socklen t *restrict address len);

The primary parameter, socket, is the socket that was introduced for accepting connections with listening. The secondary parameter, address, is the address structure that gets filled in with the address of the client. The third parameter is filled in with the length of the address structure.

Step 5) Communicate 

Now, we have connected sockets between a server and a client! Communication is a simple part. The same read and write system calls that work on files also run on sockets. We can transmit 20 bytes from the client to the server with:

char buffer[MAXBUF]; … nbytes = write(fd, buffer, 20); /* write 20 bytes in

buffer */

We can read a bunch of data from the client with:

char buffer[MAXBUF]; … nbytes = read(fd, buffer, MAXBUF); /* read up to

MAXBUF bytes */

One crucial thing to have in mind is that TCP/IP sockets provide you a byte stream, not a packet stream. If you write 20 bytes to a socket, the other side is not guaranteed to read 20 bytes in a read operation. If the volume of data you need to read matters then it’s up to you to design a protocol that permits you to know what to read, like sending a length count before sending data.

Some supported features are out-of-band data transmission, quality of service control, the ability to peek before reading incoming data, and the capability to bypass routing. The send and receive calls are similar to read and write with the addition of the flag parameter.

Step 6) Close the Connection 

When we’re finished communicating, the simplest idea to do is to close a socket with the close system call, the same close that is utilized for files. There’s another method to close connections: the shutdown system call.

#include < sys/socket.h >

intshutdown(intsocket, inthow);

The secondary parameter, how, enables us to show the socket what part of the full-duplex connection to shut down:

A value of SHUT WR will disallow further sends on that socket.

A value of SHUT RD will disallow further receives on that socket.

A value of SHUT RDWR will disallow both further sends and receives on

that socket.

Closing a socket with close(s) is similar to using shutdown(s, SHUT RDWR).

Code for Client: –

import socket

import os

s=socket.socket()

#host=socket.gethostname() #server hostname

host=’127.0.0.1′

port=12000 #same as server

s.connect((host,port))

fileToSend = open(“ToSend.txt”,”r”)

content = fileToSend.read()

s.send(content.encode())

Code for Server: –

import socket

import os

import sys

s=socket.socket()

#host=socket.gethostname()

host=’127.0.0.1′

port=12000 #ports after 6000 are free

s.bind((host,port))

s.listen(10)

while True:

c,addr=s.accept()

print “Client connected”,addr

print (‘Got Connection from’ ,addr)

content=c.recv(100).decode()

if not content:

break

print content 

Conclusion

Networking and sockets are big subjects. If you’re new to networking or sockets, don’t be intimidated by all of the acronyms and other terms. There are several things to become familiar with to know how everything works together. However, just like Python, it will begin to make more sense as you learn to understand the individual portions and give more time to them.

We believe that you would have enjoyed using our guide to socket programming in Python and hope that this tutorial would have given you the knowledge, examples, and motivation required to begin your socket development journey. Hopefully, you can utilize it to create something amazing. It could be a real-time chat app or an extraordinary smart home security system! The possibilities are endless. All the best!