1

i'm trying to transfer a file from the sender to the receiver such that the packets are not fragmented en-route. This is composed of two tasks: (1) find out the maximal fragmentation unit (MTU) of the minimal MTU on the path from the sender to the receiver, and (2) then transfer a file in packets that do not exceed the minimal MTU between a receiving and sending host.

the code that I have to the receiver is:

# ----    Imports     ---- # 
from socket import *
import sys, struct, time


# ----   Constants    ---- #
HOST            = ""
PORT            = 5555
ADDRESS         = (HOST,PORT)
PORT_MSGS               = 9999
TIMEOUT         = 0.0005
BUFFER                  = 65536


#---        Body        --- #
mtu = 0
numMsgs = 0

#make a socket
try:
    sckt = socket(AF_INET,SOCK_DGRAM)
    sckt.bind(ADDRESS)
    sckt.settimeout(TIMEOUT)
except socket.error:
    if sckt:
        sckt.close() # Socket Creation Failed
        sys.exit(1) # Exit program with error


#get mtu and number of messages
header = struct.pack('c','k')
while (1):  
    try:
        data, addr = sckt.recvfrom(BUFFER)
        char = struct.unpack('lc', data[0:5])[1]
        if (char == 'm'):
            mtu = struct.unpack('lc', data[0:5])[0]
            numMsgs = int(data[5:])
            #send ack for the mtu message
            sckt.sendto(header, (addr[0] ,PORT_MSGS))
            break
        if not(char == 'm'):
            continue
    except socket.error:
        continue
    except timeout:
        continue


mtuFileName = sys.argv[1]
fileName= sys.argv[2]

#make mtu file
mtuFile = open(mtuFileName,'wb')
mtuFile.write(str(mtu))
mtuFile.close()

f = open(fileName,'wb')

packetsBuffer = numMsgs * [0]
# Receive messages
packetCounter = 0
data, addr = sckt.recvfrom(BUFFER)
while (1):
        packetSeq = int(struct.unpack('lc', data[0:5])[0])
        char = struct.unpack('lc', data[0:5])[1]
        if (char == 'r') and (packetsBuffer[packetSeq] == 0):
            dataOfPack = data[5:]
            packetsBuffer[packetSeq] = dataOfPack
            packetCounter = packetCounter + 1
        if( numMsgs == packetCounter):
            break
        data, addr = sckt.recvfrom(BUFFER)


#write messages to file
buffIndex = 0
while (buffIndex < numMsgs):
    f.write(packetsBuffer[buffIndex])
    buffIndex = buffIndex + 1


f.close()
sckt.close() # close the socket

the sender is:

# -------    Imports    ------- #
from socket import *
import sys, struct, os, stat, commands, time


# -------   Constants    ------- #
PORT_SEND           = 5555
IP_HOST         = sys.argv[1]
SERVER_ADDRESS      = (IP_HOST  ,PORT_SEND)
MY_PORT             = 9999
MAX_FAILS_SENDING   = 10
MTU_DISCOVERY_SEQ   = 0 # the Sequence number sending MTU discovery messages
TIMEOUT             = 0.0005
BUFFER              = 65536


# -------     Body       ------- #
#socket- file
try:
    scktFile = socket(AF_INET,SOCK_DGRAM)
    scktFile.connect(SERVER_ADDRESS)
    scktFile.settimeout(TIMEOUT)
except socket.error:
    if scktFile:
        scktFile.close() # Socket Creation Failed
        sys.exit(1) # Exit program with error


#socket- ack/mtu
try:
    scktMsgs = socket(AF_INET,SOCK_DGRAM)
    scktMsgs.bind(("", MY_PORT))
    scktMsgs.settimeout(TIMEOUT)
except socket.error:
    if scktMsgs:
        scktMsgs.close() # Socket Creation Failed
        sys.exit(1) # Exit program with error


#find the mtu
mtu = int(commands.getoutput(" tracepath "+sys.argv[1]+"| grep -i resume | awk '{print $3}'"))

payloadSize = mtu-(20+8+8+5)

fileName = sys.argv[2]
f = open (fileName, 'rb') 

fileData = f.read(99999999)
fileLen = len(fileData)
numMsgs = fileLen / (payloadSize)
if((fileLen % payloadSize) != 0):
    numMsgs = numMsgs + 1


#m - mtu,k - mtu ack, a - ack, f - fin, r - regular message part of file, w - wait for ack - after  10 rounds, n -name of file
while (1):  
    header = struct.pack('lc', mtu, 'm') #m - mtu
    sNumMsgs = str(numMsgs)
    scktFile.sendto(header+sNumMsgs, SERVER_ADDRESS)
    try:
        data,addr = scktFile.recvfrom(BUFFER)
        char = struct.unpack('c', data[0])
        if char == 'k':
            break
    except socket.error:
        continue
    except timeout:
        continue


# send file content
seqNum = 0
header = struct.pack('lc', seqNum, 'r')#r - regular message part of file
while (1):
        seqNum = 0
        indexFile = 0
        header = struct.pack('lc', seqNum, 'r')
        data = fileData[indexFile:(indexFile+payloadSize)]
        indexFile = indexFile + payloadSize
        while (data):
            if(scktFile.sendto(header+data,SERVER_ADDRESS)):
                data = fileData[indexFile:(indexFile+payloadSize)]
                indexFile = indexFile+payloadSize
            #time.sleep(0.00005)
            seqNum = seqNum + 1
            seqNum = seqNum % numMsgs # Maximum Seq number
            header = struct.pack('lc', seqNum, 'r')
            if seqNum == 0:
                break


scktMsgs.close()
scktFile.close()

I keep getting the error "0 points (No Output)" and I dont know why

4

1 回答 1

0

你不能这样做。

  1. 确保传出数据包符合路径 MTU 已经是 TCP 堆栈的责任。为什么你也想在应用程序中承担这个责任对我来说是个谜。
  2. 据我所知,没有任何 API 可以在任何数据传输之前告诉您 MTU。
  3. 无法控制传出数据包的大小。TCP 是一种字节流协议,而不是数据包交换,它有权随时合并传出的数据包。关闭 Nagle 算法可以缓解这种情况,但不能保证消除它。
  4. 没有任何好处。众所周知,通过 TCP 传输批量数据的最有效方式是写入尽可能大的块;在发送方设置一个大的套接字发送缓冲区;并在接收器处设置一个大的套接字接收缓冲区。
于 2013-01-12T23:27:35.983 回答