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

Returns a new instance of Server.



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

def initialize(*args)
  super(*args)
  @logging = true
  @dot_cycle = SimpleTransfer.instance_variable_get(:@dot_cycle)
end

Instance Method Details

#copyto_local(data) ⇒ Object



104
105
106
107
108
109
110
111
112
113
# File 'lib/transfer.rb', line 104

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



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

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



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

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



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

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

#recv_chunk(size = @@recv_size) ⇒ Object



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

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

#recv_fileObject



81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/transfer.rb', line 81

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

#recv_initiationObject



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

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

#recv_part(data, data_length) ⇒ Object



73
74
75
76
77
78
79
# File 'lib/transfer.rb', line 73

def recv_part(data, data_length) 
  # no need to end sync, just check if exactly the file size is read at total
  remaining = data_length - data.length
  part = remaining < @@recv_size ? recv_chunk(remaining) : recv_chunk()
  return part
  #
end

#startObject



115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# File 'lib/transfer.rb', line 115

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