computer_network04062024[1]
computer_network04062024[1]
Broadcast Sockets:
import socket
import threading
request = client_socket.recv(1024)
print(f"Received: {request.decode()}")
client_socket.send(response.encode())
client_socket.close()
def main():
host = "127.0.0.1"
port = 12345
server_socket.bind((host, port))
server_socket.listen(5)
try:
while
client_thread.start()
except KeyboardInterrupt:
server_socket.close()
if __name__ == "__main__":
main()
This code sets up a basic TCP server that listens on localhost (127.0.0.1) and port 12345.
Each incoming connection is handled in its own thread using the handle_client function.
The server listens for connections indefinitely until interrupted by a keyboard interrupt
(Ctrl+C).
This is a simple example. In a real-world scenario, you might want to implement error
handling, graceful shutdown, and possibly use a thread pool or other concurrency
mechanisms for better scalability and resource management. Additionally, consider security
measures such as input validation and sanitization to prevent potential vulnerabilities.
4.Implementation of Data link Layer flow
control Mechanism (Stop and Wait, Sliding
Window)
The Data Link Layer's flow control mechanisms, including Stop-and-Wait and Sliding
Window, are essential for ensuring reliable data transmission between two connected devices
over a communication channel. Let's briefly discuss each mechanism and then outline their
implementations:
1. Stop-and-Wait:
o In Stop-and-Wait, the sender sends one frame at a time and waits for an
acknowledgment (ACK) from the receiver before sending the next frame.
o If the sender doesn't receive an ACK within a specified timeout period, it
assumes that the frame was lost and retransmits it.
o The receiver sends ACKs for correctly received frames, and it discards
duplicates.
Stop-and-Wait Implementation:
def sender(data):
while data:
send_frame(frame)
ack = receive_ack()
if ack:
data = data[FRAME_SIZE:]
else:
continue
def receiver():
while True:
frame = receive_frame()
if is_valid(frame):
send_ack()
deliver_data(frame)
else:
continue
2. Sliding Window:
o Sliding Window is a more efficient flow control mechanism where multiple
frames can be transmitted before waiting for acknowledgments.
o It allows the sender to transmit a specified number of frames (window size)
before receiving acknowledgments.
o Both the sender and receiver maintain a window that slides as new frames are
sent and acknowledged.
base = 0
next_seq_num = 0
frame = data[next_seq_num]
send_frame(frame, next_seq_num)
next_seq_num += 1
while True:
ack = receive_ack()
base = ack + 1
break
def receiver():
base = 0
while True:
if seq_num == base:
deliver_data(frame)
base += 1
send_ack(base)
else:
continue
5.Implementation of Data Link layer error
Detection Mechanism (Cyclic Redundancy check)
Cyclic Redundancy Check (CRC) is a popular error detection mechanism
used at the Data Link Layer to detect errors in transmitted data. Here's a
basic implementation of CRC:
CRC Encoding:
result = []
if a[i] == b[i]:
result.append('0')
else:
result.append('1')
return ''.join(result)
pick = len(divisor)
tmp = dividend[0:pick]
if tmp[0] == '1':
else:
pick += 1
if tmp[0] == '1':
else:
return tmp
def encode_data(data, key):
l_key = len(key)
return codeword
data = "1101011111"
key = "10011"
CRC Decoding:
return remainder
if remainder == '0'*(len(key)-1):
print("Data is error-free")
else:
Go-Back-N Protocol:
import socket
import threading
import time
SERVER_ADDRESS = ('localhost', 65432)
WINDOW_SIZE = 4
lock = threading.Lock()
base = 0
next_seq_num = 0
expected_seq_num = 0
buffer = []
def handle_client(client_socket, client_address):
global base, next_seq_num, expected_seq_num, buffer
print(f'Connection from {client_address}')
while True:
data, addr = client_socket.recvfrom(1024)
if not data:
break
seq_num = int(data.decode().split(':')[0])
message = data.decode().split(':')[1]
with lock:
if seq_num == expected_seq_num:
print(f"Received expected packet {seq_num} with
message: {message}")
client_socket.sendto(f"ACK:{seq_num}".encode(),
addr)
expected_seq_num += 1
while expected_seq_num in buffer:
print(f"Delivering buffered packet
{expected_seq_num} with message:
{buffer[expected_seq_num]}")
del buffer[expected_seq_num]
expected_seq_num += 1
else:
print(f"Received out of order packet {seq_num} with
message: {message}, expecting {expected_seq_num}")
buffer[seq_num] = message
client_socket.sendto(f"ACK:{expected_seq_num-
1}".encode(), addr)
client_socket.close()
def start_server():
server_socket = socket.socket(socket.AF_INET,
socket.SOCK_DGRAM)
server_socket.bind(SERVER_ADDRESS)
print(f"Server is listening on {SERVER_ADDRESS}")
while True:
data, client_address = server_socket.recvfrom(1024)
if data:
client_handler =
threading.Thread(target=handle_client, args=(server_socket,
client_address))
client_handler.start()
start_server()
TCP Server
import socket
s.bind(server_address)
s.listen()
while True:
with connection:
while True:
data = connection.recv(1024)
if not data:
break
print('Received:', data.decode())
connection.sendall(data)
TCP Client
import socket
s.connect(server_address)
try:
print('Sending:', message)
s.sendall(message.encode())
data = s.recv(1024)
print('Received:', data.decode())
finally:
print('Closing connection')
UDP server
import socket
s.bind(server_address)
while True:
UDP Client
import socket
try:
print('Sending:', message)
print('Received:', data.decode())
finally:
print('Closing socket')