Skip to content

Commit 68e6469

Browse files
author
Shashwat Kathuria
committed
Written client side program with all comments and indentaion too.
1 parent 047bb39 commit 68e6469

File tree

1 file changed

+280
-0
lines changed

1 file changed

+280
-0
lines changed

client.py

Lines changed: 280 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,280 @@
1+
# -*- coding: utf-8 -*-
2+
"""
3+
Created on Sat Nov 2 01:46:07 2019
4+
5+
@author: Shashwat Kathuria
6+
"""
7+
8+
# Client Side Program
9+
# Physical Layer and Data Link Layer Implementation
10+
11+
# Importing socket library for socket programming
12+
import socket, random
13+
import pylab as plt
14+
15+
def main():
16+
17+
# Getting required input
18+
generator = raw_input("Enter the generator function in 0s and 1s : ")
19+
finalDecodedMessage = ""
20+
while True:
21+
22+
# Configuration for socket
23+
s = socket.socket()
24+
port = 9999
25+
try:
26+
# Connecting
27+
s.connect(("127.0.0.1", port))
28+
except:
29+
break
30+
# Getting received message from server
31+
receivedMessage = s.recv(1024).decode()
32+
33+
# Decoding message from Physical Layer which itself takes help from
34+
# Data Link Layer for error detection
35+
physicalLayer = PhysicalLayer(receivedMessage)
36+
decodedMessage = physicalLayer.decode(generator)
37+
38+
# Printing Answer
39+
if decodedMessage != None:
40+
print("\nDecoded Frame Message : " + str(decodedMessage))
41+
finalDecodedMessage += str(decodedMessage)
42+
else:
43+
print("\nError detected in data by CRC (Cyclic Redundancy Check).")
44+
45+
# Plotting and showing encodings through graphs
46+
physicalLayer.plotManchesterEncoding()
47+
physicalLayer.plotOriginalEncoding()
48+
# Closing connection
49+
s.close()
50+
print("--------------------------------------")
51+
# Printing final answer
52+
print("\nFinal Decoded Message : " + str(finalDecodedMessage))
53+
print("--------------------------------------")
54+
55+
56+
class PhysicalLayer():
57+
58+
def __init__(self, bits):
59+
"""Function to initialize Physical Layer Object."""
60+
61+
self.message = ""
62+
self.bits = bits
63+
self.decodedMessage = ""
64+
self.time = list(range(len(self.bits)))
65+
self.manchesterEncoding = bits
66+
self.manchesterYVal = []
67+
self.originalYVal = []
68+
69+
def decode(self, generator):
70+
"""Function to decode data using Manchester Encoding.
71+
Generator variable used to pass onto Data Link Layer Object."""
72+
73+
# Variable to keep track of decoded part of Manchester Encoding
74+
temp = ""
75+
print("\nManchester Encoding : \n" + str(self.bits))
76+
77+
# Getting values for manchester encoding graph plot
78+
yVal = [int(x) for x in list(self.bits)]
79+
temp = []
80+
for val in yVal:
81+
if val == 0:
82+
temp.append(-1)
83+
else:
84+
temp.append(1)
85+
yVal = temp
86+
self.manchesterYVal = yVal
87+
88+
temp = ""
89+
# Decoding Manchester encoding in pairs
90+
for i in range(0, len(self.bits), 2):
91+
# Getting bits pair
92+
s = self.bits[i: i + 2]
93+
# If Low High then 1
94+
if s == "01":
95+
temp += "1"
96+
# If High Low then 0
97+
elif s == "10":
98+
temp += "0"
99+
100+
# Storing answer
101+
self.bits = temp
102+
103+
# Getting values for original encoding graph plot
104+
tempOriginalYVal = [int(x) for x in self.bits]
105+
for y in tempOriginalYVal:
106+
self.originalYVal.append(y)
107+
self.originalYVal.append(y)
108+
109+
# Decoded to original encoding with CRC Remainder
110+
print("\nOriginal Encoding With CRC Remainder : \n" + str(self.bits))
111+
112+
choice = raw_input("\nDo you deliberately want to introduce errors into the frame signal to check the program?Press 1 for yes else give any other input : ")
113+
114+
# Introducing Errors Deliberately if choice is 1
115+
if choice == "1":
116+
temp = list(self.bits)
117+
# For 5 iterations
118+
for i in range(5):
119+
index = random.randint(0, len(self.bits) - 1)
120+
if temp[index] == "0":
121+
temp[index] = "1"
122+
elif temp[index] == "1":
123+
temp[index] = "0"
124+
125+
self.bits = "".join(temp)
126+
127+
print("\nOriginal Encoding With CRC Remainder After Introducing Deliberate Errors : \n" + str(self.bits))
128+
129+
# Getting checksum
130+
CRCchecksum = DataLinkLayer(self.bits, generator).CRCdetectError()
131+
132+
# Printing checksum
133+
print("\nCRC Remainder : \n" + str(CRCchecksum))
134+
135+
# Checking further cases
136+
if CRCchecksum == '0' * (len(generator) - 1):
137+
self.bits = self.bits[:-(len(generator) - 1)]
138+
# Error case
139+
if len(self.bits) % 8 != 0:
140+
print("\nError detected in data. Number of bits not a multiple of 8.\n")
141+
return None
142+
# Correct case
143+
else:
144+
print("\nNo Error.")
145+
print("\nOriginal Encoding Without CRC Remainder : \n" + str(self.bits))
146+
return self.bitsToString()
147+
# Error case
148+
else:
149+
print("\nError detected in data. CRC Remainder is not equal to " + str('0' * (len(generator) - 1)))
150+
return None
151+
152+
153+
def bitsToString(self):
154+
"""Function to convert a stream of bits into string using ascii and bit values."""
155+
156+
# Lists to store bits and chars
157+
chars = []
158+
bitsArray = []
159+
160+
# Storing all bits in an array
161+
for i in self.bits:
162+
bitsArray.append(int(i))
163+
164+
# Converting 8 bits (each byte) into a char
165+
for b in range(len(bitsArray) // 8):
166+
167+
# Getting 8 bits/a byte
168+
byte = bitsArray[b*8:(b+1)*8]
169+
# Converting to a char and then appending to list of chars
170+
# Base 2 for bit
171+
chars.append(chr(int(''.join([str(bit) for bit in byte]), 2)))
172+
173+
# Concatenating chars and storing
174+
self.decodedMessage = ''.join(chars)
175+
176+
# Returning answer
177+
return self.decodedMessage
178+
179+
def plotManchesterEncoding(self):
180+
"""Function to plot Manchester Encoding."""
181+
182+
# Plotting and configuring the graph
183+
plt.figure("Graph")
184+
plt.title("Manchester Encoding")
185+
plt.clf()
186+
plt.xlim(0, len(self.time))
187+
plt.xlabel("Time || Manchester Encoding")
188+
plt.ylabel("Encoding Value")
189+
plt.plot(self.time, self.manchesterYVal, drawstyle='steps-post')
190+
plt.show()
191+
192+
def plotOriginalEncoding(self):
193+
"""Function to plot Original Encoding."""
194+
195+
# Plotting and configuring the graph
196+
plt.figure("Graph")
197+
plt.title("Original Encoding")
198+
plt.clf()
199+
plt.xlim(0, len(self.time))
200+
plt.xlabel("Time || Original Encoding")
201+
plt.ylabel("Encoding Value")
202+
plt.plot(self.time, self.originalYVal, drawstyle='steps-post')
203+
plt.show()
204+
205+
class DataLinkLayer():
206+
def __init__(self, bits, generator):
207+
"""Function to initialize Data Link Layer Object."""
208+
209+
self.bits = bits
210+
self.keyLength = len(generator)
211+
self.appendedData = self.bits + "0" * (self.keyLength - 1)
212+
self.generator = generator
213+
214+
def CRCdetectError(self):
215+
"""Function to encode data using CRC(Cyclic Redundancy Checksum)."""
216+
217+
divisor = self.generator
218+
divident = self.appendedData
219+
220+
# Number of bits to be xored
221+
numBits = len(self.generator)
222+
223+
# Subpart substring
224+
subpartSubstring = self.appendedData[0 : numBits]
225+
226+
while numBits < len(self.appendedData):
227+
228+
# If Leftmost bit is 1
229+
if subpartSubstring[0] == '1':
230+
231+
# Using self.generator and appending a data bit at the end
232+
subpartSubstring = self.XOR(self.generator, subpartSubstring) + self.appendedData[numBits]
233+
# Else if leftmost bit is 0
234+
else:
235+
# Using all '0's generator
236+
subpartSubstring = self.XOR('0'*numBits, subpartSubstring) + divident[numBits]
237+
238+
# increment numBits to move further
239+
numBits += 1
240+
241+
# For the last nth bits, otherwise out of bound occurs due to numBits
242+
# If Leftmost bit is 1
243+
if subpartSubstring[0] == '1':
244+
245+
# Using self.generator
246+
subpartSubstring = self.XOR(divisor, subpartSubstring)
247+
# Else if leftmost bit is 0
248+
else:
249+
250+
# Using all '0's generator
251+
subpartSubstring = self.XOR('0' * numBits, subpartSubstring)
252+
253+
# Returning checksum answer
254+
checksum = subpartSubstring
255+
return checksum
256+
257+
def XOR(self, messagePartition, generator):
258+
"""Function to xor a messagePartition and generator.
259+
Also cutting of first bit of xor."""
260+
261+
# Variable required
262+
self.xor = ""
263+
# Iterating through bits at respective positions
264+
for bit1, bit2 in zip(messagePartition, generator):
265+
# XORing
266+
if bit1 == bit2:
267+
self.xor = self.xor + "0"
268+
else:
269+
self.xor = self.xor + "1"
270+
271+
# Returning answer
272+
return self.xor[1 : ]
273+
274+
275+
276+
277+
278+
# Calling main function
279+
if __name__ == "__main__":
280+
main()

0 commit comments

Comments
 (0)