Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

MFTP Server and Client. Help would be greatly appreciated! PLEASE make sure it r

ID: 3824557 • Letter: M

Question

MFTP Server and Client. Help would be greatly appreciated! PLEASE make sure it runs in command prompt/terminal! Will send some Bitcoin to whoever answer if they fit all the guidelines! Just put your wallet at the end!

: -> Java Implementation of a reliable data transfer protocol on top of UDP sockets using Go-Back-N protocol with window size equal to 4 packets.

Build a simple File Transfer Service that consists of a client and server. The server exports a set of files from the computer on which it runs to be downloaded on the client computer. That is: a client requests a file from the server and the server responds to the client by sending the file. Client will request one file at a time. Server will send the contents of the file followed by the end-of-transmission packet and then exits. Client must save the file on the local computer with the same file name. Server records all file download activities in a log file. Build the MFTP on UDP ports. Use sequence number on data blocks to enforce reliability.

The message from the client and the response from the server are transmitted as the content of UDP datagrams. Each message is identified by a packet type as follows:

Packet type| Explanation

0 | ACK packet(i.e., acknowledgement packet).
1 | Request a file to be read from the server i.e., this packet carries file name to be downloaded.
2 | Data packet, i.e, contains data being transferred
3 | Reports an error [error message: File not found]
4 | EOT packet, i.e., it is an end-of-transmission (EOT) packet

Format of the UDP packet being transmitted between the client and the server is:

Type of the packet Sequence number Length (data size) Data (<= 16 bytes), depending on the packet type.
The EOT packet is in the same format as a regular data packet, except that its type field is set to 4 and its length is set to zero.
The server can close its connection and exit only after it has received ACKs for all data packets it has sent.
The length field specifies the number of characters carried in the data field. It should be in the range of 0 to 15.


For ACK packets, length should be set to zero.
Implementation:
Both client and server will run from the command line as follows: >client >server The is the name of the file to be downloaded from the server.

The RN is used by the server to emulate lost packets as,

If RN = 0 all packets are received by the receiver,

If RN = 1 first packet of the current winodw is lost,

If RN = 2 all packets of the current window are lost.

Output: In order to observe the performance of the sliding window protocol and to check whether the implementation is working properly, collect statistics. Collect statistics for both the client and server. After transferring a file print out the following suggested statistics
1. the total number of data packets transmitted
2. the total number of retransmissions
3. the total number of acknowledgments sent
4. the total number of acknowledgments received
5. the total number of duplicate packets received
6. the total amount of data sent.

7. A log file of actions, recording all activities between the client and server.

Explanation / Answer

import pdb

import time

import select

import socket

import errno

import sys

from struct import *

from collections import namedtuple

DEBUG = False

E_INVALID_PARAMS = 2

E_FILE_READ_FAIL = 69

E_NO_SERVER = 70

SPORT = 7735

CPORT = 7736

DATA_ID = 0b0101010101010101

ACK_ID = 0b1010101010101010

HEADER_LEN = 8

TIMEOUT = .1

stmp = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

stmp.connect(("g_mail.com",80))

me = stmp.getsockname()[0]

stmp.close()

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

sock.bind((me, CPORT))

sock.setblocking(0)

pkt = namedtuple("pkt", ["seq_num", "chk_sum", "pkt_type", "data", "acked"])

ack = namedtuple("pkt", ["seq_num", "chk_sum", "pkt_type"])

if len(sys.argv) != 6:

print "Usage: ./client <shost> <sport> <file_name> <N> <MSS>"

sys.exit(E_INVALID_PARAMS)

shost = str(sys.argv[1])

sport = int(sys.argv[2])

file_name = str(sys.argv[3])

window_size = int(sys.argv[4])

mss = int(sys.argv[5])

if DEBUG:

print "CLIENT: shost:", shost, " CLIENT: sport:", sport, " CLIENT: file_name:",

file_name, " CLIENT: window_size:", window_size, " CLIENT: mss:", mss

def carry_around_add(a, b):

c = a + b

return (c & 0xffff) + (c >> 16)

def checksum(msg):

if (len(msg) % 2) != 0:

msg += "0"

s = 0

for i in range(0, len(msg), 2):

w = ord(msg[i]) + (ord(msg[i+1]) << 8)

s = carry_around_add(s, w)

return ~s & 0xffff

def send_pkt(pkt, sock):

if DEBUG:

print "CLIENT: Packing checksum", pkt.chk_sum, "seq_num", pkt.seq_num

raw_pkt = pack('iHH' + str(len(pkt.data)) + 's', pkt.seq_num, int(pkt.chk_sum),

pkt.pkt_type, pkt.data)

sock.sendto(raw_pkt, (shost, sport))

def parse_ack(pkt_raw):

new_pkt = ack._make(unpack('iHH', pkt_raw))

return new_pkt

def build_pkts(file_data):

seq_num = 0

pkts = []

sent = 0

to_send = min(mss - HEADER_LEN, len(file_data) - sent)

while to_send > 0:

pkts.append(pkt(seq_num = seq_num, chk_sum = checksum(file_data[sent:sent

+ to_send]), pkt_type = DATA_ID, data = file_data[sent:sent + to_send],

acked = False))

if DEBUG:

print "CLIENT: Built pkt with seq_num", seq_num

sent += to_send

to_send = min(mss - HEADER_LEN, len(file_data) - sent)

seq_num += 1

return pkts

def rdt_send(file_data):

# Build packet list

pkts = build_pkts(file_data)

oldest_unacked = 0

unacked = 0

while oldest_unacked < len(pkts):

if unacked < window_size and (unacked + oldest_unacked) < len(pkts):

send_pkt(pkts[oldest_unacked + unacked], sock)

if DEBUG:

print "CLIENT: Sent pkt to", str(shost) + ":" +    str(sport)

unacked += 1

continue

else:

ready = select.select([sock], [], [], TIMEOUT)

if ready[0]:

pkt_recv_raw, addr = sock.recvfrom(4096)

if DEBUG:

print "CLIENT: Packet received from", addr

else:

if DEBUG:

print "CLIENT: No pkt received with timeout", TIMEOUT

print "CLIENT: Go-back-N because of full window and no ACK after timeout"

print "Timeout, sequence number =", oldest_unacked

unacked = 0

continue

if addr[0] != shost:

if DEBUG:

print "CLIENT: Unexpected pkt from", addr

continue

pkt_recv = parse_ack(pkt_recv_raw)

if pkt_recv.pkt_type != ACK_ID:

if DEBUG:

print "CLIENT: Unexpected pkt type", pkt_recv.pkt_type, ", dropping pkt"

continue

if pkt_recv.seq_num == oldest_unacked:

oldest_unacked += 1

unacked -= 1

if DEBUG:

print "CLIENT: oldest_unacked updated, now", oldest_unacked

print "CLIENT: unacked updated, now", unacked

else:

if DEBUG:

print "CLIENT: Out of order pkt. Expected", oldest_unacked,

"received", pkt_recv.seq_num

print "CLIENT: Go-back-N with unacked", unacked, "== window_size",

window_size

unacked = 0

continue

print "CLIENT: File successfully transfered"

sock.close()

sys.exit(0)

try:

fd = open(file_name, 'r')

file_data = fd.read()

fd.close()

except:

print "Failed to open file:", file_name

sys.exit(E_FILE_READ_FAIL)

if file_data == "":

print "No data read from file. Is it empty?"

sys.exit(E_FILE_READ_FAIL)

rdt_send(file_data)