Class: SimpleTransfer::Server

Inherits:
TCPServer
  • Object
show all
Defined in:
lib/transfer.rb

Constant Summary collapse

@@recv_size =
1024 * 30

Instance Method Summary collapse

Constructor Details

#initialize(*args) ⇒ Server



22
23
24
25
# File 'lib/transfer.rb', line 22

def initialize(*args)
  super(*args)
  @logging = true
end

Instance Method Details

#copyto_local(data) ⇒ Object



95
96
97
98
99
100
101
102
103
104
# File 'lib/transfer.rb', line 95

def copyto_local(data)
  fdata, filename = data
  dirname = File.dirname(filename)
  if not File.exist?('.' + dirname)
    FileUtils.mkdir_p(dirname)
  end
  File.open(filename, "wb") do |f|
    f.write(fdata)
  end
end

#handle_initObject



61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/transfer.rb', line 61

def handle_init()
  init_data = recv_initiation()
  if init_data == nil
    log_transfer("Failed to receive initiation data", level = "WARNING") if @logging
    return false, nil
  elsif init_data == 0
    log_transfer("Connection closed by the client", level = "WARNING") if @logging
    return false, 0
    return false, init_data
  end
  return init_data
end

#init_transferObject



35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/transfer.rb', line 35

def init_transfer()
  @conn.send("SYNC OK", 1024)
  data_length = Integer(recv_chunk()) # receive data length
  log_transfer("received data length: #{data_length}", level = "DEBUGGING") if @logging
  @conn.send("LENGTH OK", 1024)
  filename = recv_chunk() # receive file name
  log_transfer("received filename: #{filename}", level = "DEBUGGING") if @logging
  @conn.send("FILENAME OK", 1024)
  log_transfer(
    "transfer initiated for #{filename} size: #{data_length}", level = "INFO"
  ) if @logging
  return data_length, filename
end

#portObject



27
28
29
# File 'lib/transfer.rb', line 27

def port()
  return self.addr[1]
end

#recv_chunkObject



31
32
33
# File 'lib/transfer.rb', line 31

def recv_chunk()
  return @conn.recv(@@recv_size)
end

#recv_fileObject



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/transfer.rb', line 74

def recv_file()
  init = handle_init()
  if not init[0]
    return init[1]
  end
  data_length, filename = init
  data = ""
  while data.length < data_length
    data += recv_chunk()
    sleep(0.01)
    log_progress(data.length, data_length, filename) if @logging
  end
  Kernel.print "\n"
  if data.length != data_length
    log_transfer(
      "partial data received for #{filename}", level = "WARNING"
    ) if @logging
  end
  return data, filename
end

#recv_initiationObject



49
50
51
52
53
54
55
56
57
58
59
# File 'lib/transfer.rb', line 49

def recv_initiation()
  start_sign = recv_chunk() # wait for the client to sync
  log_transfer("received start sign: #{start_sign}", level = "DEBUGGING") if @logging
  if start_sign != "SYNC NOW"
    if start_sign.empty?
      return 0
    end
    return nil
  end
  return init_transfer()
end

#startObject



106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/transfer.rb', line 106

def start()
  log_transfer("(Re)starting Simple-Transfer server!") if @logging
  log_transfer("listening at port %s..." % port) if @logging
  self.listen(16)
  @conn = accept()
  log_transfer("Accepted client: #{@conn.peeraddr[2]}: #{@conn.peeraddr[1]}")
  while true
    filedata = recv_file()
    if filedata == nil
      next
    elsif filedata == 0
      start()
      return
    end
    copyto_local(filedata)
    sleep 0.01
  end
end