2013-01-12 72 views
1

我試圖將文件從發件人傳輸到接收方,使數據包在途中沒有分段。它由兩個任務組成:(1)找出從發送方到接收方的路徑上最小MTU的最大分片單元(MTU),(2)然後以不超過最小MTU的分組傳輸文件在接收和發送主機之間。傳輸帶有套接字的文件,並找到最大MTU

,我有到接收器的代碼是:

# ---- 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 

發件人是:

# ------- 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() 

我不斷收到錯誤 「0分(無輸出)」 和我不知道爲什麼

回答

0

你不能這樣做。

  1. 確保傳出數據包符合路徑MTU已經是TCP堆棧的責任。爲什麼你會想在應用程序中承擔責任,這對我來說是個謎。
  2. 沒有任何API可以告訴你任何數據傳輸之前的MTU。
  3. 無法控制傳出數據包大小。 TCP是一種字節流協議,而不是數據包交換,並且只要感覺像它一樣,它有權合併傳出的數據包。關閉Nagle算法可以減輕這一點,但不能保證消除它。
  4. 沒有好處。通過TCP傳輸批量數據的最有效方式是儘可能以大塊寫入;在發送方設置一個大的套接字發送緩衝區;並在接收器處設置一個大的套接字接收緩衝區。