├── 3. Client Server CRC code ├── CRC.PNG ├── vrc-lrc.py ├── server.py ├── CRCcode.py ├── client.py └── Problem Statement.rtf ├── 2. Practice Problem ├── Question ├── client.py └── server.py ├── 1. String Reverse (Client-Server) Python ├── ReverseString.PNG ├── client.py └── server.py ├── Multi-Threading ├── SampleDictionaryworking.py ├── client2.py └── server1.py ├── Message-Length ├── README.md ├── client.py └── server.py ├── googleconnect.py ├── Socket_C ├── client.c └── server1.c └── README.md /3. Client Server CRC code/CRC.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shauryauppal/Socket-Programming-Python/HEAD/3. Client Server CRC code/CRC.PNG -------------------------------------------------------------------------------- /2. Practice Problem/Question: -------------------------------------------------------------------------------- 1 | Write a client server python program to send input from client to server, replace all the vowels with '#' and return the string to client and print it. 2 | -------------------------------------------------------------------------------- /1. String Reverse (Client-Server) Python/ReverseString.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shauryauppal/Socket-Programming-Python/HEAD/1. String Reverse (Client-Server) Python/ReverseString.PNG -------------------------------------------------------------------------------- /2. Practice Problem/client.py: -------------------------------------------------------------------------------- 1 | import socket 2 | 3 | s = socket.socket() 4 | 5 | port = 12345 6 | 7 | s.connect(('127.0.0.1', port)) 8 | 9 | 10 | 11 | input_string = raw_input("Enter data you want to send->") 12 | s.sendall(input_string) 13 | 14 | print s.recv(1024) 15 | 16 | s.close() 17 | -------------------------------------------------------------------------------- /Multi-Threading/SampleDictionaryworking.py: -------------------------------------------------------------------------------- 1 | #dictionary item no. ('itemname',price) 2 | d = {'1':('tomato',20),'2':('potato',10),'3':('onion',40),'4':('carrot',10),'5':('apple',45)} 3 | #print dictionry 4 | print(d) 5 | #iterator using key values 6 | for keys in d.keys(): 7 | #method1 8 | print(d[keys][0],d[keys][1]) 9 | #method2 10 | name,cost = d[keys] 11 | print('Keys->',keys,'Grocery -> :',name,'\n','The cost is :',cost) 12 | 13 | -------------------------------------------------------------------------------- /Multi-Threading/client2.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | import socket 4 | 5 | 6 | def Main(): 7 | host = '127.0.0.1' 8 | port = 5559 9 | s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) 10 | s.connect((host,port)) 11 | message = input('Enter the Grocery item number ->') 12 | while True: 13 | s.send(message.encode('ascii')) 14 | data = s.recv(1024) 15 | print('Recieved from the server :',str(data.decode('ascii'))) 16 | ans = input('\nWant to buy more :') 17 | if ans == 'y': 18 | message = input('Enter the Grocery item number-> ->') 19 | else: 20 | break 21 | s.close() 22 | 23 | if __name__ == '__main__': 24 | Main() 25 | -------------------------------------------------------------------------------- /1. String Reverse (Client-Server) Python/client.py: -------------------------------------------------------------------------------- 1 | # Import socket module 2 | import socket 3 | 4 | # Create a socket object 5 | s = socket.socket() 6 | 7 | # Define the port on which you want to connect 8 | port = 12345 9 | 10 | # connect to the server on local computer 11 | s.connect(('127.0.0.1', port)) 12 | 13 | # Send data to server 'Hello world' 14 | 15 | ## s.sendall('Hello World') 16 | 17 | input_string = input("Enter data you want to send->") 18 | s.sendall(bytes(input_string,'utf-8')) 19 | 20 | # receive data from the server 21 | print(s.recv(1024).decode()) 22 | 23 | # close the connection 24 | s.close() 25 | -------------------------------------------------------------------------------- /Message-Length/README.md: -------------------------------------------------------------------------------- 1 | # Message Length 2 | 3 | The default / standard way of receiving data from a socket in Python is to pull a buffer size until there is no more data to receive. 4 | This method has no concept for how long a message is, so the idea here is to pull the first 4 bytes of the message to obtain the message size. 5 | The server / client will then pull N chunks where N is the `ceil(message length / buffer size)` to get the rest of the message. 6 | The message length could also be used for other purposes such as limiting/prohibiting longer messages if the service calls for it. 7 | 8 | The only other additional thing the server/client of message length does here is JSON encode/decoding to send more structured data to and from the sockets. 9 | -------------------------------------------------------------------------------- /googleconnect.py: -------------------------------------------------------------------------------- 1 | # An example script to connect to Google using socket 2 | # programming in Python 3 | import socket # for socket 4 | import sys 5 | 6 | try: 7 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 8 | print "Socket successfully created" 9 | except socket.error as err: 10 | print "socket creation failed with error %s" %(err) 11 | 12 | # default port for socket 13 | port = 80 14 | 15 | try: 16 | host_ip = socket.gethostbyname('www.google.com') 17 | except socket.gaierror: 18 | 19 | # this means could not resolve the host 20 | print "there was an error resolving the host" 21 | sys.exit() 22 | 23 | # connecting to the server 24 | s.connect((host_ip, port)) 25 | 26 | print "the socket has successfully connected to google \ 27 | on port == %s" %(host_ip) 28 | -------------------------------------------------------------------------------- /2. Practice Problem/server.py: -------------------------------------------------------------------------------- 1 | import socket 2 | 3 | s = socket.socket() 4 | print "Socket successfully created" 5 | 6 | 7 | port = 12345 8 | 9 | s.bind(('', port)) 10 | print "socket binded to %s" %(port) 11 | 12 | s.listen(5) 13 | print "socket is listening" 14 | 15 | while True: 16 | 17 | c, addr = s.accept() 18 | print 'Got connection from', addr 19 | 20 | data=c.recv(1024) 21 | 22 | a="" 23 | for i in range(0,len(data)): 24 | if(data[i]=='a' or data[i]=='e' or data[i]=='i' or data[i]=='o' or data[i]=='u' or data[i]=='A' or data[i]=='E' or data[i]=='I' or data[i]=='O'): 25 | a=a+'#' 26 | else: 27 | a=a+data[i] 28 | 29 | if not data: 30 | break 31 | 32 | c.sendall(a) 33 | 34 | 35 | c.close() 36 | -------------------------------------------------------------------------------- /Multi-Threading/server1.py: -------------------------------------------------------------------------------- 1 | import socket 2 | from _thread import * 3 | import threading 4 | print_lock = threading.Lock() 5 | d = {'1':('tomato',20),'2':('potato',10),'3':('onion',40),'4':('carrot',10),'5':('apple',45)} 6 | def threaded(c): 7 | while True: 8 | print('\nList what the store has->') 9 | for keys in d.keys(): 10 | name , cost = d[keys] 11 | print('Keys->',keys,'Grocery -> :',name,'\n','The cost is :',cost) 12 | data = c.recv(1024) 13 | if not data: 14 | print('Bye') 15 | print_lock.release() 16 | break 17 | name , cost = d[str(data.decode('ascii'))] 18 | print('Grocery selected-> :',name,'\n','Cost-> :',cost) 19 | ans = input('\nDo you want to checkout->') 20 | if ans =='y': 21 | c.send(str.encode('\nYour bill is :'+str(cost))) 22 | else: 23 | print('Thank u') 24 | c.close() 25 | 26 | def Main(): 27 | host = "" 28 | port = 5559 29 | s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) 30 | s.bind((host,port)) 31 | s.listen(5) 32 | while True: 33 | c,addr = s.accept() 34 | print_lock.acquire() 35 | print('Connected to :',addr[0],':',addr[1]) 36 | start_new_thread(threaded,(c,)) 37 | s.close() 38 | 39 | 40 | if __name__ == '__main__': 41 | Main() 42 | -------------------------------------------------------------------------------- /1. String Reverse (Client-Server) Python/server.py: -------------------------------------------------------------------------------- 1 | # first of all import the socket library 2 | import socket 3 | 4 | # next create a socket object 5 | s = socket.socket() 6 | print("Socket successfully created") 7 | 8 | # reserve a port on your computer in our 9 | # case it is 12345 but it can be anything 10 | port = 12345 11 | 12 | # Next bind to the port 13 | # we have not typed any ip in the ip field 14 | # instead we have inputted an empty string 15 | # this makes the server listen to requests 16 | # coming from other computers on the network 17 | s.bind(('', port)) 18 | print("socket binded to",port) 19 | 20 | # put the socket into listening mode 21 | s.listen(5) 22 | print("socket is listening") 23 | 24 | # a forever loop until we interrupt it or 25 | # an error occurs 26 | while True: 27 | 28 | # Establish connection with client. 29 | c, addr = s.accept() 30 | print('Got connection from', addr) 31 | 32 | # Get data from client 33 | data=c.recv(1024).decode() 34 | 35 | #Reverse data received from client 36 | data = data[::-1] 37 | 38 | if not data: 39 | break 40 | 41 | # Send back reversed data to client 42 | c.sendall(bytes(data,'utf-8')) 43 | 44 | 45 | # send a thank you message to the client. 46 | #c.send('\n Thank you for sending message!!!!') 47 | 48 | # Close the connection with the client 49 | c.close() 50 | -------------------------------------------------------------------------------- /Socket_C/client.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int main(){ 7 | int clientSocket; 8 | char buffer[1024]; 9 | struct sockaddr_in serverAddr; 10 | socklen_t addr_size; 11 | 12 | /*---- Create the socket. The three arguments are: ----*/ 13 | /* 1) Internet domain 2) Stream socket 3) Default protocol (TCP in this case) */ 14 | clientSocket = socket(PF_INET, SOCK_STREAM, 0); 15 | 16 | /*---- Configure settings of the server address struct ----*/ 17 | /* Address family = Internet */ 18 | serverAddr.sin_family = AF_INET; 19 | /* Set port number, using htons function to use proper byte order */ 20 | serverAddr.sin_port = htons(7891); 21 | /* Set IP address to localhost */ 22 | serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); 23 | /* Set all bits of the padding field to 0 */ 24 | memset(serverAddr.sin_zero, '\0', sizeof serverAddr.sin_zero); 25 | 26 | /*---- Connect the socket to the server using the address struct ----*/ 27 | addr_size = sizeof serverAddr; 28 | connect(clientSocket, (struct sockaddr *) &serverAddr, addr_size); 29 | 30 | scanf("%s",&buffer); 31 | send(clientSocket,buffer,1024,0); 32 | /*---- Read the message from the server into the buffer ----*/ 33 | recv(clientSocket, buffer, 1024, 0); 34 | 35 | /*---- Print the received message ----*/ 36 | printf("Data received: %s",buffer); 37 | 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /3. Client Server CRC code/vrc-lrc.py: -------------------------------------------------------------------------------- 1 | import sys 2 | val1= 'hi' 3 | 4 | if (len(sys.argv)>1): 5 | val1=str(sys.argv[1]) 6 | 7 | def parityOf(int_type): 8 | parity = 0 9 | while (int_type): 10 | parity = ~parity 11 | int_type = int_type & (int_type-1) 12 | 13 | if (parity==-1): 14 | return(0) 15 | return(1) 16 | 17 | def calcLRC(input): 18 | 19 | lrc = ord(input[0]) 20 | 21 | for i in range(1,len(input)): 22 | lrc ^= ord(input[i]) 23 | return lrc 24 | 25 | 26 | def showLRC(input,res): 27 | input = input[:7] 28 | 29 | print 'Char\tHex\tBinary' 30 | print '------------------------------------' 31 | for i in range(0,len(input)): 32 | print input[i],"\t",hex(ord(input[i])),"\t",bin(ord(input[i])) 33 | 34 | 35 | print '\nBit\tBinary LRC' 36 | print '----------------------------' 37 | print ' \t', 38 | for i in range(0,len(input)): 39 | print input[i], 40 | print "" 41 | 42 | mask=1 43 | for bitpos in range(0,7): 44 | bit = (res & mask) >> bitpos 45 | print "b",bitpos,"\t", 46 | 47 | for i in range(0,len(input)): 48 | bitchar = (ord(input[i]) & mask) >> bitpos 49 | print bitchar, 50 | 51 | print bit 52 | mask = mask << 1 53 | 54 | # Show VRC 55 | print "VRC\t", 56 | for i in range(0,len(input)): 57 | print parityOf(ord(input[i])), 58 | 59 | print parityOf(res), 60 | return 61 | 62 | res = calcLRC(val1) 63 | 64 | print "" 65 | print "Input: ",val1," LRC is ",hex(res),"- Char: ",chr(res) 66 | print "" 67 | 68 | showLRC(val1,res) 69 | 70 | 71 | -------------------------------------------------------------------------------- /Socket_C/server1.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int main(){ 7 | int welcomeSocket, newSocket; 8 | char buffer[1024]; 9 | struct sockaddr_in serverAddr; 10 | struct sockaddr_storage serverStorage; 11 | socklen_t addr_size; 12 | 13 | /*---- Create the socket. The three arguments are: ----*/ 14 | /* 1) Internet domain 2) Stream socket 3) Default protocol (TCP in this case) */ 15 | welcomeSocket = socket(PF_INET, SOCK_STREAM, 0); 16 | 17 | /*---- Configure settings of the server address struct ----*/ 18 | /* Address family = Internet */ 19 | serverAddr.sin_family = AF_INET; 20 | /* Set port number, using htons function to use proper byte order */ 21 | serverAddr.sin_port = htons(7891); 22 | /* Set IP address to localhost */ 23 | serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); 24 | /* Set all bits of the padding field to 0 */ 25 | memset(serverAddr.sin_zero, '\0', sizeof serverAddr.sin_zero); 26 | 27 | /*---- Bind the address struct to the socket ----*/ 28 | bind(welcomeSocket, (struct sockaddr *) &serverAddr, sizeof(serverAddr)); 29 | 30 | /*---- Listen on the socket, with 5 max connection requests queued ----*/ 31 | if(listen(welcomeSocket,5)==0) 32 | printf("Listening\n"); 33 | else 34 | printf("Error\n"); 35 | 36 | /*---- Accept call creates a new socket for the incoming connection ----*/ 37 | addr_size = sizeof serverStorage; 38 | newSocket = accept(welcomeSocket, (struct sockaddr *) &serverStorage, &addr_size); 39 | 40 | recv(newSocket, buffer, 1024, 0); 41 | buffer[0]='#'; 42 | /*---- Send message to the socket of the incoming connection ----*/ 43 | //strcpy(buffer,"Hello World\n"); 44 | send(newSocket,buffer,1024,0); 45 | 46 | return 0; 47 | } 48 | -------------------------------------------------------------------------------- /Message-Length/client.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import json 4 | import struct 5 | import socket 6 | 7 | # type: obj -> str 8 | def encode(data): 9 | return json.dumps(data) 10 | 11 | # type: str -> obj 12 | def decode(data): 13 | return json.loads(data) 14 | 15 | def main(host, port, recv_msg_len, recv_buffer): 16 | s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) 17 | 18 | # connect to server on local computer 19 | s.connect((host,port)) 20 | 21 | # message you send to server 22 | message = encode({ 23 | "name": "test-message", 24 | "message": "sending message to socket client" 25 | }) 26 | 27 | while True: 28 | # message sent to server 29 | msg = struct.pack(">I", len(message)) + message.encode("utf-8") 30 | s.send(msg) 31 | 32 | # messaga received from server 33 | data = None 34 | total_len = 0 35 | while total_len < self.RECV_MSG_LEN: 36 | msg_len = sock.recv(recv_msg_len) 37 | total_len = total_len + len(msg_len) 38 | 39 | # If the message has the length prefix 40 | if msg_len: 41 | data = "" 42 | msg_len = struct.unpack(">I", msg_len)[0] 43 | total_data_len = 0 44 | while total_data_len < msg_len: 45 | chunk = sock.recv(recv_buffer) 46 | 47 | if not chunk: 48 | data = None 49 | break 50 | else: 51 | data = data + chunk.decode("utf-8") 52 | total_data_len = total_data_len + len(chunk) 53 | 54 | # print the received message 55 | # here it would be a reverse of sent message 56 | print("Received from the server :", decode(data).get("message", "")) 57 | 58 | # ask the client whether he wants to continue 59 | ans = input("\nDo you want to continue(y/n) :") 60 | if ans == "y": 61 | continue 62 | else: 63 | break 64 | 65 | # close the connection 66 | s.close() 67 | 68 | if __name__ == "__main__": 69 | main("127.0.0.1", 10101, 4, 1024) 70 | -------------------------------------------------------------------------------- /3. Client Server CRC code/server.py: -------------------------------------------------------------------------------- 1 | # first of all import the socket library 2 | import socket 3 | 4 | 5 | def xor(a, b): 6 | result = [] 7 | 8 | for i in range(1, len(b)): 9 | if a[i] == b[i]: 10 | result.append('0') 11 | else: 12 | result.append('1') 13 | 14 | return ''.join(result) 15 | 16 | 17 | 18 | def mod2div(divident, divisor): 19 | pick = len(divisor) 20 | 21 | tmp = divident[0: pick] 22 | 23 | while pick < len(divident): 24 | 25 | if tmp[0] == '1': 26 | 27 | tmp = xor(divisor, tmp) + divident[pick] 28 | 29 | else: 30 | tmp = xor('0' * pick, tmp) + divident[pick] 31 | 32 | pick += 1 33 | 34 | if tmp[0] == '1': 35 | tmp = xor(divisor, tmp) 36 | else: 37 | tmp = xor('0' * pick, tmp) 38 | 39 | checkword = tmp 40 | return checkword 41 | 42 | 43 | def decodeData(data, key): 44 | l_key = len(key) 45 | 46 | appended_data = data + '0' * (l_key - 1) 47 | remainder = mod2div(appended_data, key) 48 | 49 | # Return the remainder 50 | return remainder 51 | ''' 52 | print("Remainder : ", remainder) 53 | print("Encoded Data (Data + Remainder) : ", 54 | codeword) 55 | ''' 56 | 57 | # Creating Socket 58 | s = socket.socket() 59 | print ("Socket successfully created") 60 | 61 | # reserve a port on your computer in our 62 | # case it is 12345 but it can be anything 63 | port = 12345 64 | 65 | s.bind(('', port)) 66 | print ("socket binded to %s" % (port)) 67 | # put the socket into listening mode 68 | s.listen(5) 69 | print ("socket is listening") 70 | 71 | 72 | while True: 73 | # Establish connection with client. 74 | c, addr = s.accept() 75 | print('Got connection from', addr) 76 | 77 | # Get data from client 78 | data = c.recv(1024) 79 | 80 | print(data) 81 | 82 | if not data: 83 | break 84 | 85 | key = "1001" 86 | 87 | ans = decodeData(data, key) 88 | print("Remainder after decoding is->"+ans) 89 | 90 | # If remainder is all zeros then no error occured 91 | temp = "0" * (len(key) - 1) 92 | if ans == temp: 93 | c.sendall("THANK you Data ->"+data + " Received No error FOUND") 94 | else: 95 | c.sendall("Error in data") 96 | 97 | c.close() -------------------------------------------------------------------------------- /3. Client Server CRC code/CRCcode.py: -------------------------------------------------------------------------------- 1 | ''' 2 | st="abc" 3 | #convert string to binary 4 | print(' '.join(format(ord(x), 'b') for x in st)) 5 | 6 | #print(bin(4)) 7 | print('*******') 8 | for x in st: 9 | print(bin(ord(x))) 10 | ''' 11 | ''' 12 | str = "HI" 13 | ans = (''.join(format(ord(x), 'b') for x in str)) 14 | print(ans,type(ans)) 15 | 16 | CRC = input('Enter CRC-') 17 | len_CRC = len(CRC) 18 | print(len_CRC) 19 | k=ans # stored original to k 20 | 21 | # Append len_CRC-1 bit to k 22 | k+="0"*(len_CRC-1) 23 | print(k) 24 | k=ans 25 | 26 | #while(True): 27 | ''' 28 | # Returns XOR of 'a' and 'b' 29 | # (both of same length) 30 | def xor(a, b): 31 | 32 | # initialize result 33 | result = [] 34 | 35 | # Traverse all bits, if bits are 36 | # same, then XOR is 0, else 1 37 | for i in range(1, len(b)): 38 | if a[i] == b[i]: 39 | result.append('0') 40 | else: 41 | result.append('1') 42 | 43 | return ''.join(result) 44 | 45 | 46 | # Performs Modulo-2 division 47 | def mod2div(divident, divisor): 48 | 49 | # Number of bits to be XORed at a time. 50 | pick = len(divisor) 51 | 52 | # Slicing the divident to appropriate 53 | # length for particular step 54 | tmp = divident[0 : pick] 55 | 56 | while pick < len(divident): 57 | 58 | if tmp[0] == '1': 59 | 60 | # replace the divident by the result 61 | # of XOR and pull 1 bit down 62 | tmp = xor(divisor, tmp) + divident[pick] 63 | 64 | else: # If leftmost bit is '0' 65 | # If the leftmost bit of the dividend (or the 66 | # part used in each step) is 0, the step cannot 67 | # use the regular divisor; we need to use an 68 | # all-0s divisor. 69 | tmp = xor('0'*pick, tmp) + divident[pick] 70 | 71 | # increment pick to move further 72 | pick += 1 73 | 74 | # For the last n bits, we have to carry it out 75 | # normally as increased value of pick will cause 76 | # Index Out of Bounds. 77 | if tmp[0] == '1': 78 | tmp = xor(divisor, tmp) 79 | else: 80 | tmp = xor('0'*pick, tmp) 81 | 82 | checkword = tmp 83 | return checkword 84 | 85 | # Function used at the sender side to encode 86 | # data by appending remainder of modular divison 87 | # at the end of data. 88 | def encodeData(data, key): 89 | 90 | l_key = len(key) 91 | 92 | # Appends n-1 zeroes at end of data 93 | appended_data = data + '0'*(l_key-1) 94 | remainder = mod2div(appended_data, key) 95 | 96 | # Append remainder in the original data 97 | codeword = data + remainder 98 | print("Remainder : ", remainder) 99 | print("Encoded Data (Data + Remainder) : ", 100 | codeword) 101 | 102 | # Driver code 103 | data = "100010110101101001110" 104 | key = "1001" 105 | encodeData(data, key) 106 | 107 | 108 | 109 | 110 | -------------------------------------------------------------------------------- /3. Client Server CRC code/client.py: -------------------------------------------------------------------------------- 1 | # Import socket module 2 | import socket 3 | 4 | 5 | 6 | def xor(a, b): 7 | 8 | # initialize result 9 | result = [] 10 | 11 | # Traverse all bits, if bits are 12 | # same, then XOR is 0, else 1 13 | for i in range(1, len(b)): 14 | if a[i] == b[i]: 15 | result.append('0') 16 | else: 17 | result.append('1') 18 | 19 | return ''.join(result) 20 | 21 | 22 | # Performs Modulo-2 division 23 | def mod2div(divident, divisor): 24 | 25 | # Number of bits to be XORed at a time. 26 | pick = len(divisor) 27 | 28 | # Slicing the divident to appropriate 29 | # length for particular step 30 | tmp = divident[0 : pick] 31 | 32 | while pick < len(divident): 33 | 34 | if tmp[0] == '1': 35 | 36 | # replace the divident by the result 37 | # of XOR and pull 1 bit down 38 | tmp = xor(divisor, tmp) + divident[pick] 39 | 40 | else: # If leftmost bit is '0' 41 | # If the leftmost bit of the dividend (or the 42 | # part used in each step) is 0, the step cannot 43 | # use the regular divisor; we need to use an 44 | # all-0s divisor. 45 | tmp = xor('0'*pick, tmp) + divident[pick] 46 | 47 | # increment pick to move further 48 | pick += 1 49 | 50 | # For the last n bits, we have to carry it out 51 | # normally as increased value of pick will cause 52 | # Index Out of Bounds. 53 | if tmp[0] == '1': 54 | tmp = xor(divisor, tmp) 55 | else: 56 | tmp = xor('0'*pick, tmp) 57 | 58 | checkword = tmp 59 | return checkword 60 | 61 | # Function used at the sender side to encode 62 | # data by appending remainder of modular divison 63 | # at the end of data. 64 | def encodeData(data, key): 65 | 66 | l_key = len(key) 67 | 68 | # Appends n-1 zeroes at end of data 69 | appended_data = data + '0'*(l_key-1) 70 | remainder = mod2div(appended_data, key) 71 | 72 | # Append remainder in the original data 73 | codeword = data + remainder 74 | return codeword 75 | ''' 76 | print("Remainder : ", remainder) 77 | print("Encoded Data (Data + Remainder) : ", 78 | codeword) 79 | ''' 80 | 81 | 82 | 83 | 84 | 85 | # Create a socket object 86 | s = socket.socket() 87 | 88 | # Define the port on which you want to connect 89 | port = 12345 90 | 91 | # connect to the server on local computer 92 | s.connect(('127.0.0.1', port)) 93 | 94 | # Send data to server 'Hello world' 95 | 96 | ## s.sendall('Hello World') 97 | 98 | input_string = raw_input("Enter data you want to send->") 99 | #s.sendall(input_string) 100 | data =(''.join(format(ord(x), 'b') for x in input_string)) 101 | print (data) 102 | key = "1001" 103 | 104 | ans = encodeData(data,key) 105 | print(ans) 106 | s.sendall(ans) 107 | 108 | 109 | # receive data from the server 110 | print (s.recv(1024)) 111 | 112 | # close the connection 113 | s.close() 114 | -------------------------------------------------------------------------------- /Message-Length/server.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import json 4 | import socket 5 | import select 6 | import struct 7 | import threading 8 | 9 | # type: obj -> str 10 | def encode(data): 11 | return json.dumps(data) 12 | 13 | # type: str -> obj 14 | def decode(data): 15 | return json.loads(data) 16 | 17 | _HOST = "127.0.0.1" 18 | _PORT = 10101 19 | 20 | class SocketServer(threading.Thread): 21 | MAX_WAITING_CONNECTIONS = 5 22 | RECV_BUFFER = 4096 23 | RECV_MSG_LEN = 4 24 | def __init__(self, host, port): 25 | threading.Thread.__init__(self) 26 | self.host = host 27 | self.port = port 28 | self.connections = [] 29 | self.running = True 30 | 31 | def _bind_socket(self): 32 | self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 33 | self.server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 34 | self.server_socket.bind((self.host, self.port)) 35 | self.server_socket.listen(self.MAX_WAITING_CONNECTIONS) 36 | self.connections.append(self.server_socket) 37 | 38 | @classmethod 39 | def _send(cls, sock, msg): 40 | # Append message with length of message 41 | msg = struct.pack(">I", len(msg)) + msg.encode("utf-8") 42 | sock.send(msg) 43 | 44 | def _receive(self, sock): 45 | data = None 46 | total_len = 0 47 | while total_len < self.RECV_MSG_LEN: 48 | msg_len = sock.recv(self.RECV_MSG_LEN) 49 | total_len = total_len + len(msg_len) 50 | 51 | # If the message has the length prefix 52 | if msg_len: 53 | data = "" 54 | msg_len = struct.unpack(">I", msg_len)[0] 55 | total_data_len = 0 56 | while total_data_len < msg_len: 57 | chunk = sock.recv(self.RECV_BUFFER) 58 | 59 | if not chunk: 60 | data = None 61 | break 62 | else: 63 | data = data + chunk.decode("utf-8") 64 | total_data_len = total_data_len + len(chunk) 65 | 66 | return data 67 | 68 | def _broadcast(self, client_socket, client_message): 69 | print("Starting broadcast...") 70 | for sock in self.connections: 71 | not_server = (sock != self.server_socket) 72 | not_sending_client = (sock != client_socket) 73 | if not_server and not_sending_client: 74 | try: 75 | print("Broadcasting: %s" % client_message) 76 | self._send(sock, client_message) 77 | except socket.error: 78 | # Client no longer replying 79 | print("Closing a socket...") 80 | sock.close() 81 | self.connections.remove(sock) 82 | 83 | def _run(self): 84 | print("Starting socket server (%s, %s)..." % (self.host, self.port)) 85 | while self.running: 86 | try: 87 | # Timeout every 60 seconds 88 | selection = select.select(self.connections, [], [], 5) 89 | read_sock = selection[0] 90 | except select.error: 91 | print("Error!!!") 92 | else: 93 | for sock in read_sock: 94 | # New connection 95 | if sock == self.server_socket: 96 | try: 97 | accept_sock = self.server_socket.accept() 98 | client_socket, client_address = accept_sock 99 | except socket.error: 100 | print("Other error!") 101 | break 102 | else: 103 | self.connections.append(client_socket) 104 | print("Client (%s, %s) is online" % client_address) 105 | 106 | self._broadcast(client_socket, encode({ 107 | "name": "connected", 108 | "data": client_address 109 | })) 110 | # Existing client connection 111 | else: 112 | try: 113 | data = self._receive(sock) 114 | if data: 115 | print(decode(data)) 116 | self._send(sock, data) 117 | except socket.error: 118 | # Client is no longer replying 119 | self._broadcast(sock, encode({ 120 | "name": "disconnected", 121 | "data": client_address 122 | })) 123 | print("Client (%s, %s) is offline" % client_address) 124 | sock.close() 125 | self.connections.remove(sock) 126 | continue 127 | # Clear the socket connection 128 | self.stop() 129 | 130 | def run(self): 131 | self._bind_socket() 132 | self._run() 133 | 134 | def stop(self): 135 | self.running = False 136 | self.server_socket.close() 137 | 138 | if __name__ == "__main__": 139 | socket_server = SocketServer(_HOST, _PORT) 140 | socket_server.start() 141 | -------------------------------------------------------------------------------- /3. Client Server CRC code/Problem Statement.rtf: -------------------------------------------------------------------------------- 1 | {\rtf1\ansi\deff3\adeflang1025 2 | {\fonttbl{\f0\froman\fprq2\fcharset0 Times New Roman;}{\f1\froman\fprq2\fcharset2 Symbol;}{\f2\fswiss\fprq2\fcharset0 Arial;}{\f3\froman\fprq2\fcharset0 Liberation Serif{\*\falt Times New Roman};}{\f4\froman\fprq2\fcharset0 Arial;}{\f5\froman\fprq2\fcharset0 Calibri;}{\f6\froman\fprq2\fcharset0 Times New Roman;}{\f7\fnil\fprq2\fcharset0 Lucida Sans;}{\f8\fnil\fprq2\fcharset0 Calibri;}{\f9\fnil\fprq2\fcharset0 Times New Roman;}{\f10\fnil\fprq2\fcharset0 Microsoft YaHei;}} 3 | {\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;} 4 | {\stylesheet{\s0\snext0\nowidctlpar\hyphpar0\cf0\kerning1\dbch\af11\langfe2052\dbch\af12\afs24\alang1081\loch\f3\fs24\lang16393 Normal;} 5 | {\s15\sbasedon20\snext16\ql\nowidctlpar\sb240\sa120\keepn\ltrpar\cf1\dbch\af7\langfe1081\dbch\af10\afs24\loch\f4\fs28\lang16393 Heading;} 6 | {\s16\sbasedon0\snext16\sl288\slmult1\sb0\sa140 Text Body;} 7 | {\s17\sbasedon21\snext17\ql\nowidctlpar\sb0\sa120\ltrpar\cf1\dbch\af7\langfe1081\dbch\af8\afs24\loch\f5\fs24\lang16393 List;} 8 | {\s18\sbasedon20\snext18\ql\nowidctlpar\sb120\sa120\ltrpar\cf1\i\dbch\af7\langfe1081\dbch\af8\afs24\loch\f5\fs24\lang16393 Caption;} 9 | {\s19\sbasedon20\snext19\ql\nowidctlpar\ltrpar\cf1\dbch\af7\langfe1081\dbch\af8\afs24\loch\f5\fs24\lang16393 Index;} 10 | {\s20\snext20\ql\nowidctlpar\ltrpar\hyphpar0\cf1\dbch\af8\langfe1081\dbch\af8\afs24\kerning1\alang1081\loch\f5\fs24\lang16393 Default;} 11 | {\s21\sbasedon20\snext21\ql\nowidctlpar\sb0\sa120\ltrpar\cf1\dbch\af8\langfe1081\dbch\af8\afs24\loch\f5\fs24\lang16393 Text body;} 12 | }{\*\generator LibreOffice/5.1.6.2$Linux_X86_64 LibreOffice_project/10m0$Build-2}{\info{\creatim\yr0\mo0\dy0\hr0\min0}{\revtim\yr2018\mo7\dy29\hr23\min58}{\printim\yr0\mo0\dy0\hr0\min0}}\deftab720\deftab720 13 | \viewscale100 14 | {\*\pgdsctbl 15 | {\pgdsc0\pgdscuse451\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\pgdscnxt0 Default Style;}} 16 | \formshade{\*\pgdscno0}\paperh15840\paperw12240\margl1800\margr1800\margt1440\margb1440\sectd\sbknone\sectunlocked1\pgndec\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\ftnbj\ftnstart1\ftnrstcont\ftnnar\aenddoc\aftnrstcont\aftnstart1\aftnnrlc 17 | {\*\ftnsep}\pgndec\pard\plain \s20\ql\nowidctlpar\ltrpar\hyphpar0\cf1\dbch\af8\langfe1081\dbch\af8\afs24\kerning1\alang1081\loch\f5\fs24\lang16393\sl276\slmult1\nowidctlpar\li0\ri0\lin0\rin0\fi0\sb0\sa200{\kerning1\dbch\af9\dbch\af9\rtlch \ltrch\loch\fs28\loch\f6 18 | Implement the following events with a multi-client server TCP program in Python } 19 | \par \pard\plain \s20\ql\nowidctlpar\ltrpar\hyphpar0\cf1\dbch\af8\langfe1081\dbch\af8\afs24\kerning1\alang1081\loch\f5\fs24\lang16393\sl276\slmult1\nowidctlpar\tx1440\li720\ri0\lin720\rin0\fi-360\sb0\sa200{\rtlch \ltrch 20 | }{\rtlch \ltrch\loch 21 | 1\tab }{\kerning1\dbch\af9\dbch\af9\rtlch \ltrch\loch\fs22\loch\f6 22 | \u61623\'3f }{\kerning1\dbch\af9\dbch\af9\rtlch \ltrch\loch\fs28\loch\f6 23 | Establish a connection b/w the two clients C1, C2 and one server S. } 24 | \par \pard\plain \s20\ql\nowidctlpar\ltrpar\hyphpar0\cf1\dbch\af8\langfe1081\dbch\af8\afs24\kerning1\alang1081\loch\f5\fs24\lang16393\sl276\slmult1\nowidctlpar\tx1440\li720\ri0\lin720\rin0\fi-360\sb0\sa200{\rtlch \ltrch 25 | }{\rtlch \ltrch\loch 26 | 2\tab }{\kerning1\dbch\af9\dbch\af9\rtlch \ltrch\loch\fs22\loch\f6 27 | \u61623\'3f }{\kerning1\dbch\af9\dbch\af9\rtlch \ltrch\loch\fs28\loch\f6 28 | C1 sends the following data \u8220\'93EVN\u8221\'94 to server. } 29 | \par \pard\plain \s20\ql\nowidctlpar\ltrpar\hyphpar0\cf1\dbch\af8\langfe1081\dbch\af8\afs24\kerning1\alang1081\loch\f5\fs24\lang16393\sl276\slmult1\nowidctlpar\tx1440\li720\ri0\lin720\rin0\fi-360\sb0\sa200{\rtlch \ltrch 30 | }{\rtlch \ltrch\loch 31 | 3\tab }{\kerning1\dbch\af9\dbch\af9\rtlch \ltrch\loch\fs22\loch\f6 32 | \u61623\'3f }{\kerning1\dbch\af9\dbch\af9\rtlch \ltrch\loch\fs28\loch\f6 33 | C2 sends the following data \u8220\'93 C2\u8221\'94 to server S. } 34 | \par \pard\plain \s20\ql\nowidctlpar\ltrpar\hyphpar0\cf1\dbch\af8\langfe1081\dbch\af8\afs24\kerning1\alang1081\loch\f5\fs24\lang16393\sl276\slmult1\nowidctlpar\tx1440\li720\ri0\lin720\rin0\fi-360\sb0\sa200{\rtlch \ltrch 35 | }{\rtlch \ltrch\loch 36 | 4\tab }{\kerning1\dbch\af9\dbch\af9\rtlch \ltrch\loch\fs22\loch\f6 37 | \u61623\'3f }{\kerning1\dbch\af9\dbch\af9\rtlch \ltrch\loch\fs28\loch\f6 38 | Sever calculates the CRC with 1001 for C1 and C2 data.} 39 | \par \pard\plain \s20\ql\nowidctlpar\ltrpar\hyphpar0\cf1\dbch\af8\langfe1081\dbch\af8\afs24\kerning1\alang1081\loch\f5\fs24\lang16393\sl276\slmult1\nowidctlpar\tx2160\li1080\ri0\lin1080\rin0\fi-360\sb0\sa200{\rtlch \ltrch 40 | }{\rtlch \ltrch\loch 41 | 1\tab }{\kerning1\dbch\af9\dbch\af9\rtlch \ltrch\loch\fs22\loch\f6 42 | \u61623\'3f }{\kerning1\dbch\af9\dbch\af9\rtlch \ltrch\loch\fs28\loch\f6 43 | Server resends the new data along with the CRC bits in binary format to both the } 44 | \par \pard\plain \s20\ql\nowidctlpar\ltrpar\hyphpar0\cf1\dbch\af8\langfe1081\dbch\af8\afs24\kerning1\alang1081\loch\f5\fs24\lang16393\sl276\slmult1\nowidctlpar\tx3600\li1800\ri0\lin1800\rin0\fi-360\sb0\sa200{\rtlch \ltrch 45 | }{\rtlch \ltrch\loch 46 | 1.1.1\tab }{\kerning1\dbch\af9\dbch\af9\rtlch \ltrch\loch\fs28\loch\f6 47 | Clients. } 48 | \par \pard\plain \s20\ql\nowidctlpar\ltrpar\hyphpar0\cf1\dbch\af8\langfe1081\dbch\af8\afs24\kerning1\alang1081\loch\f5\fs24\lang16393\sl276\slmult1\nowidctlpar\tx1440\li720\ri0\lin720\rin0\fi-360\sb0\sa200{\rtlch \ltrch 49 | }{\rtlch \ltrch\loch 50 | 5\tab }{\kerning1\dbch\af9\dbch\af9\rtlch \ltrch\loch\fs22\loch\f6 51 | \u61623\'3f }{\kerning1\dbch\af9\dbch\af9\rtlch \ltrch\loch\fs28\loch\f6 52 | Client checks for error with the same key (1001), and displays the appropriate } 53 | \par \pard\plain \s20\ql\nowidctlpar\ltrpar\hyphpar0\cf1\dbch\af8\langfe1081\dbch\af8\afs24\kerning1\alang1081\loch\f5\fs24\lang16393\sl276\slmult1\nowidctlpar\tx1440\li720\ri0\lin720\rin0\fi-360\sb0\sa200{\rtlch \ltrch 54 | }{\rtlch \ltrch\loch 55 | 6\tab }{\kerning1\dbch\af9\dbch\af9\rtlch \ltrch\loch\fs28\loch\f6 56 | messages for positive and negative ACKs. } 57 | \par } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Guide to Socket Programming Introduction 2 | [![HitCount](http://hits.dwyl.io/shauryauppal/Socket-Programming-Python.svg)](https://github.com/shauryauppal/Socket-Programming-Python) [![MadeIn](https://img.shields.io/badge/MADE%20IN-PYTHON-darkblue.svg)](https://github.com/shauryauppal/Socket-Programming-Python) [![MadeIn](https://img.shields.io/badge/MADE%20IN-C-yellowgreen.svg)](https://github.com/shauryauppal/Socket-Programming-Python/tree/master/Socket_C) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com) 3 | [![GitHub stars](https://img.shields.io/github/stars/shauryauppal/Socket-Programming-Python.svg)](https://github.com/shauryauppal/Socket-Programming-Python/stargazers) 4 | 5 | ## Socket programming is started by socket library 6 | 7 | ``` 8 | import socket 9 | s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) 10 | ``` 11 | 12 | + AF_INET refers to address family ipv4 13 | + SOCK_STREAM meaning TCP protocol 14 | 15 | ***************** 16 | 17 | ## SERVER code 18 | + s = socket.socket() 19 | + It simply creates a new socket using the given address family,socket type and protocol number. 20 | + port = 12345 21 | + Reserves a port for computer 22 | + s.bind('',port) 23 | + We binded our server to the specified port. Passing an empty string means that the server can listen to incoming connections from other computers as well. If we would have passed 127.0.0.1 then it would have listened to only those calls made within the local computer. 24 | + s.listen(5) 25 | + Server can connect to 5 clients, 6th or more clients are rejected. 26 | + s.accept() 27 | + Return new socket object c and address 28 | + s.close() 29 | + Marks the socket closed, all future operaions on socket will be failed. 30 | 31 | #### OverView 32 | ``` 33 | #import library 34 | import socket 35 | 36 | s=socket.socket() 37 | port=12345 38 | s.bind('',port) 39 | s.listen(5) 40 | 41 | while True: 42 | c,addr = s.accept() 43 | data = c.recv(1024) 44 | c.sendall(data) 45 | c.close() 46 | ``` 47 | Server uses `bind() , listen() , accept()` 48 | ************* 49 | ## Client Code 50 | 51 | + First create socket object 52 | + Give port number same as server 53 | + connect() '127.0.0.1' local machine connection 54 | + print s.recv(1024) #print data recv from socket 55 | + close() connection 56 | ``` 57 | import socket 58 | s=socketsocket() 59 | port=12345 60 | s.connect('127.0.0.1',port) 61 | print s.recv(1024) 62 | s.close() 63 | ``` 64 | 65 | 66 | 67 | ## Reference Link 68 | + [Explaination and sample program geeksforgeeks](http://www.geeksforgeeks.org/socket-programming-python/) 69 | + [Sample Program python socket programming](http://www.bogotobogo.com/python/python_network_programming_server_client.php) 70 | 71 | **************** 72 | ## CRC Socket PROGRAMMING 73 | [Article Link](https://www.geeksforgeeks.org/cyclic-redundancy-check-python/) 74 | 75 | 76 | 77 | 78 | *************** 79 | ## Note - In **Socket_C** socket programming alternate C code is also added. 80 | 81 | *************************** 82 | # SOCKET PROGRAMMING WITH MULTI-THREADING 83 | ### Checkout My Article [Socket Programming Multi-Threading At Geeksforgeeks](http://www.geeksforgeeks.org/socket-programming-multi-threading-python/) 84 | 85 | ## Socket Programming-> 86 | It helps us to connect a client to a server. Client is message sender and receiver and server is just a listener that works on data sent by client. 87 | 88 | ## What is a Thread? 89 | A thread is a light-weight process that does not require much memory overhead, they are cheaper than processes. 90 | 91 | ## What is Multi-threading Socket Programming? 92 | Multithreading is a process of executing multiple threads simultaneously in a single process. 93 | 94 | ## Multi-threading Modules :  95 | A *_thread module & threading module* is used for multi-threading in python, these modules help in synchronization and provide a lock to a thread in use. 96 | 97 | ``` 98 | from _thread import * 99 | import threading 100 | ``` 101 | A lock object is created by-> 102 | 103 | `print_lock = threading.Lock()` 104 | 105 | A lock has two states, "locked" or "unlocked". It has two basic methods acquire() and release(). When the state is unlocked **print_lock.acquire()** is used to change state to locked and **print_lock.release()** is used to change state to unlock. 106 | 107 | The function **thread.start_new_thread()** is used to start a new thread and return its identifier. The first argument is the function to call and its second argument is a tuple containing the positional list of arguments. 108 | 109 | Let's study client-server multithreading socket programming by code-\ 110 | *Note:-The code works with python3.* 111 | 112 | # Multi-threaded Server Code 113 | 114 | 115 | ``` 116 | # import socket programming library 117 | import socket 118 | 119 | # import thread module 120 | from _thread import * 121 | import threading 122 | 123 | print_lock = threading.Lock() 124 | 125 | # thread fuction 126 | def threaded(c): 127 | while True: 128 | 129 | # data received from client 130 | data = c.recv(1024) 131 | if not data: 132 | print('Bye') 133 | 134 | # lock released on exit 135 | print_lock.release() 136 | break 137 | 138 | # reverse the given string from client 139 | data = data[::-1] 140 | 141 | # send back reversed string to client 142 | c.send(data) 143 | 144 | # connection closed 145 | c.close() 146 | 147 | 148 | def Main(): 149 | host = "" 150 | 151 | # reverse a port on your computer 152 | # in our case it is 12345 but it 153 | # can be anything 154 | port = 12345 155 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 156 | s.bind((host, port)) 157 | print("socket binded to post", port) 158 | 159 | # put the socket into listening mode 160 | s.listen(5) 161 | print("socket is listening") 162 | 163 | # a forever loop until client wants to exit 164 | while True: 165 | 166 | # establish connection with client 167 | c, addr = s.accept() 168 | 169 | # lock acquired by client 170 | print_lock.acquire() 171 | print('Connected to :', addr[0], ':', addr[1]) 172 | 173 | # Start a new thread and return its identifier 174 | start_new_thread(threaded, (c,)) 175 | s.close() 176 | 177 | 178 | if __name__ == '__main__': 179 | Main() 180 | ``` 181 | ``` 182 | Console Window: 183 | socket binded to post 12345 184 | socket is listening 185 | Connected to : 127.0.0.1 : 11600 186 | Bye 187 | ``` 188 | # Client Code 189 | ``` 190 | # Import socket module 191 | import socket 192 | 193 | 194 | def Main(): 195 | # local host IP '127.0.0.1' 196 | host = '127.0.0.1' 197 | 198 | # Define the port on which you want to connect 199 | port = 12345 200 | 201 | s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) 202 | 203 | # connect to server on local computer 204 | s.connect((host,port)) 205 | 206 | # message you send to server 207 | message = "shaurya says geeksforgeeks" 208 | while True: 209 | 210 | # message sent to server 211 | s.send(message.encode('ascii')) 212 | 213 | # messaga received from server 214 | data = s.recv(1024) 215 | 216 | # print the received message 217 | # here it would be a reverse of sent message 218 | print('Received from the server :',str(data.decode('ascii'))) 219 | 220 | # ask the client whether he wants to continue 221 | ans = input('\nDo you want to continue(y/n) :') 222 | if ans == 'y': 223 | continue 224 | else: 225 | break 226 | # close the connection 227 | s.close() 228 | 229 | if __name__ == '__main__': 230 | Main() 231 | ``` 232 | 233 | ``` 234 | Console Window: 235 | Received from the server : skeegrofskeeg syas ayruahs 236 | 237 | Do you want to continue(y/n) :y 238 | Received from the server : skeegrofskeeg syas ayruahs 239 | 240 | Do you want to continue(y/n) :n 241 | 242 | Process finished with exit code 0 243 | ``` 244 | Reference->\ 245 | 246 | 247 | ************************* 248 | ## Contributions 249 | Issues and Pull requests are most welcome. 250 | 251 | ************* 252 | GitAds 253 | 254 | --- 255 | 256 | ### Author: 257 | #### Shaurya Uppal 258 | shauryauppal00111@gmail.com 259 | 260 | Feel free to mail me for any queries. 261 | 262 | #### If this helped you in any way gift me a cup of coffee :coffee: 263 | [![paypal](https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=UXSREFS2VFSWU) 264 | --------------------------------------------------------------------------------