cloudFPGA (cF) API  1.0
The documentation of the source code of cloudFPGA (cF)
tc_TcpRecv Namespace Reference

Functions

def tcp_rx_loop (clientSock, serverSock, size, ip_da, tcp_dp, count, verbose=False)
 
def tcp_rx_ramp (clientSock, serverSock, ip_da, tcp_dp, verbose=False, start=1, end=0xFFFF)
 

Variables

 parser = argparse.ArgumentParser(description='A script to receive TCP data from an FPGA module.')
 
 type
 
 str
 
 default
 
 help
 
 int
 
 action
 
 args = parser.parse_args()
 
 ipFpga = getFpgaIpv4(args)
 
 instId = getInstanceId(args)
 
 ipResMngr = getResourceManagerIpv4(args)
 
 portFpgaServer = XMIT_MODE_LSN_PORT
 
 portResMngr = getResourceManagerPort(args)
 
tuple fpgaServerAssociation = (str(ipFpga), portFpgaServer)
 
 tcpClientSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 
 hostname = socket.gethostname()
 
 ipHostStr = socket.gethostbyname(hostname)
 
 ip4Str = ni.ifaddresses(itf)[AF_INET][0]['addr']
 
 ipHost = int(ipaddress.IPv4Address(ipHostStr))
 
int dpHost = 2718
 
tuple hostListenAssociation = (str(ipHostStr), dpHost)
 
 tcpListenSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 
 reqMsgAsBytes = struct.pack(">IHH", ipHost, dpHost, 0)
 
 tcpServerSock
 
 fpgaClientAssociation
 
 seed = args.seed
 
int TODO_MAX_SEG_SIZE = 2048
 
 size = args.size
 
 count = args.loop_count
 
 verbose = args.verbose
 

Function Documentation

◆ tcp_rx_loop()

def tc_TcpRecv.tcp_rx_loop (   clientSock,
  serverSock,
  size,
  ip_da,
  tcp_dp,
  count,
  verbose = False 
)
TCP Rx Single-Thread Loop.
 Requests the FPGA to send 'count' segments of 'size' bytes and expect the HOST to receive
  them on the socket (ip_da, tcp_port). Each segment is made of the following repetitive
  pattern '48692066726f6d200x464d4b553630210a' which decodes into "Hi from FMKU60\n".
 :param clientSock The socket to send to.
 :param serverSock The socket to receive from.
 :param size       The size of the expected segment.
 :param ip_da      The destination address of the host.
 :param tcp_dp     The destination port of the host.
 :param count      The number of segments to receive.
 :param verbose    Enables verbosity.
 :return           None

Definition at line 44 of file tc_TcpRecv.py.

44 def tcp_rx_loop(clientSock, serverSock, size, ip_da, tcp_dp, count, verbose=False):
45  """TCP Rx Single-Thread Loop.
46  Requests the FPGA to send 'count' segments of 'size' bytes and expect the HOST to receive
47  them on the socket (ip_da, tcp_port). Each segment is made of the following repetitive
48  pattern '48692066726f6d200x464d4b553630210a' which decodes into "Hi from FMKU60\n".
49  :param clientSock The socket to send to.
50  :param serverSock The socket to receive from.
51  :param size The size of the expected segment.
52  :param ip_da The destination address of the host.
53  :param tcp_dp The destination port of the host.
54  :param count The number of segments to receive.
55  :param verbose Enables verbosity.
56  :return None"""
57  if verbose:
58  print("[INFO] Requesting the FPGA to send %d segments of %d bytes on TCP port number %d." % (count, size, tcp_dp))
59  nrErr = 0
60  loop = 0
61  totalReceivedBytes = 0
62 
63  # Set the client and server sockets non-blocking
64  # -----------------------------------------------
65  clientSock.settimeout(5)
66  clientSock.setblocking(False)
67  serverSock.settimeout(5)
68  serverSock.setblocking(False)
69 
70  # Request the test to generate a segment of length='size' and to send it to socket={ip_da, tcp_dp}
71  # by sending 'ip_da', 'tcp_dp' and 'size' to the FPGA.
72  # Turn the 'ip_da' into an unsigned int binary and 'tcp_dp' and 'size' into an unsigned short binary data.
73  reqMsgAsBytes = struct.pack(">IHH", ip_da, tcp_dp, size)
74  if verbose:
75  print("[DEBUG] >>> reqMsgAsBytes = %s" % reqMsgAsBytes)
76 
77  startTime = datetime.datetime.now()
78  while loop < count:
79  # SEND message length request to FPGA
80  # ------------------------------------
81  try:
82  clientSock.sendall(reqMsgAsBytes)
83  except socket.error as exception:
84  # Any exception
85  print("[EXCEPTION] Socket error while transmitting :: %s" % exception)
86  exit(1)
87  finally:
88  pass
89 
90  # RECEIVE message length bytes from FPGA
91  # ---------------------------------------
92  currRxByteCnt = 0
93  nonBlockingTrials = 0
94  while currRxByteCnt < size:
95  try:
96  data = serverSock.recv(MTU)
97  except IOError as e:
98  # On non blocking connections - when there are no incoming data, error is going to be raised
99  # Some operating systems will indicate that using AGAIN, and some using WOULDBLOCK error code
100  # We are going to check for both - if one of them - that's expected, means no incoming data,
101  # continue as normal. If we got different error code - something happened
102  if e.errno != errno.EAGAIN and e.errno != errno.EWOULDBLOCK:
103  print('\n[ERROR] Socket reading error: {}'.format(str(e)))
104  exit(1)
105  # We just did not receive anything
106  if nonBlockingTrials > 100000:
107  print('\n[ERROR] Too many socket read attempts ({:d})'.format(nonBlockingTrials))
108  break
109  else:
110  nonBlockingTrials += 1
111  if verbose and (nonBlockingTrials % 100 == 0):
112  # print("[DEBUG] So far we received %d bytes out of %d." % (currRxByteCnt, size))
113  print(".", end="")
114  continue
115  except socket.error as exc:
116  # Any other exception
117  print("\n[EXCEPTION] Socket error while receiving :: %s" % exc)
118  exit(1)
119  else:
120  currRxByteCnt += len(data)
121  if verbose:
122  print("\n[INFO] Loop=%6d | RxBytes=%3d | " % (loop, len(data)))
123  print("RxData=%s" % data)
124  # [FIXME-TODO: assess the stream of received bytes]
125  nonBlockingTrials = 0
126  finally:
127  pass
128  totalReceivedBytes += currRxByteCnt
129  loop += 1
130  endTime = datetime.datetime.now()
131  elapseTime = endTime - startTime
132 
133  if totalReceivedBytes < 1000000:
134  print("[INFO] Received a total of %d bytes." % totalReceivedBytes)
135  elif totalReceivedBytes < 1000000000:
136  megaBytes = (totalReceivedBytes * 1.0) / (1024 * 1024 * 1.0)
137  print("[INFO] Received a total of %.1f MB." % megaBytes)
138  else:
139  gigaBytes = (totalReceivedBytes * 1.0) / (1024 * 1024 * 1024 * 1.0)
140  print("[INFO] Transferred a total of %.1f GB." % gigaBytes)
141 
142  bandwidth = (totalReceivedBytes * 8 * 1.0) / (elapseTime.total_seconds() * 1024 * 1024)
143  print("#####################################################")
144  if bandwidth < 1000:
145  print("#### TCP Rx DONE with bandwidth = %6.1f Mb/s" % bandwidth)
146  else:
147  bandwidth = bandwidth / 1000
148  print("#### TCP Rx DONE with bandwidth = %2.1f Gb/s" % bandwidth)
149  if (totalReceivedBytes != (size * count)):
150  print("#### [WARNING] TCP data loss = %.1f%%" % (100 - (totalReceivedBytes) / (size * count)))
151  # [FIXME] Should return an error code
152  print("#####################################################")
153  print()
154 
155 
def tcp_rx_loop(clientSock, serverSock, size, ip_da, tcp_dp, count, verbose=False)
Definition: tc_TcpRecv.py:44

◆ tcp_rx_ramp()

def tc_TcpRecv.tcp_rx_ramp (   clientSock,
  serverSock,
  ip_da,
  tcp_dp,
  verbose = False,
  start = 1,
  end = 0xFFFF 
)
TCP Rx Single-Thread Ramp.
Requests the FPGA to send 'start'-'end' number of segments to the HOST, each segment with an
 increasing number of bytes from 'start' to 'end'. Expect the HOST to receive the segments
 on the socket (ip_da, tcp_port). Each segment is made of the following repetitive pattern
 pattern '48692066726f6d200x464d4b553630210a' which decodes into "Hi from FMKU60\n".
 :param clientSock The socket to send to.
 :param serverSock The socket to receive from.
 :param ip_da      The destination address of the host
 :param tcp_dp     The destination port of the host.
 :param verbose    Enables verbosity.
 :param start      The start size of the ramp (in bytes).
 :param end        The end size of the ramp (in bytes).
 :return           None

Definition at line 156 of file tc_TcpRecv.py.

156 def tcp_rx_ramp(clientSock, serverSock, ip_da, tcp_dp, verbose=False, start=1, end=0xFFFF):
157  """TCP Rx Single-Thread Ramp.
158  Requests the FPGA to send 'start'-'end' number of segments to the HOST, each segment with an
159  increasing number of bytes from 'start' to 'end'. Expect the HOST to receive the segments
160  on the socket (ip_da, tcp_port). Each segment is made of the following repetitive pattern
161  pattern '48692066726f6d200x464d4b553630210a' which decodes into "Hi from FMKU60\n".
162  :param clientSock The socket to send to.
163  :param serverSock The socket to receive from.
164  :param ip_da The destination address of the host
165  :param tcp_dp The destination port of the host.
166  :param verbose Enables verbosity.
167  :param start The start size of the ramp (in bytes).
168  :param end The end size of the ramp (in bytes).
169  :return None"""
170  if verbose:
171  print("[INFO] Requesting the FPGA to send a ramp of segments of increasing size from %d to %d bytes." % (
172  start, end))
173  nrErr = 0
174  loop = 0
175  totalReceivedBytes = 0
176 
177  # Set the client and server sockets non-blocking
178  # -----------------------------------------------
179  clientSock.settimeout(5)
180  clientSock.setblocking(False)
181  serverSock.settimeout(5)
182  serverSock.setblocking(False)
183 
184  startTime = datetime.datetime.now()
185 
186  for size in range(start, end+1):
187 
188  # Request the test to generate a segment of length='size' and to send it to
189  # socket={ip_da, tcp_dp}. This procedure is triggered by sending 'ip_da', 'tcp_dp' and
190  # 'size' to the FPGA.
191  reqMsgAsBytes = struct.pack(">IHH", ip_da, tcp_dp, size)
192  if verbose:
193  print("[DEBUG] Requesting a segment of size=%d bytes (reqMsgAsBytes = %s)" % (size, reqMsgAsBytes))
194 
195  # SEND message length request to FPGA
196  # ------------------------------------
197  try:
198  clientSock.sendall(reqMsgAsBytes)
199  except socket.error as exception:
200  # Any exception
201  print("[EXCEPTION] Socket error while transmitting :: %s" % exception)
202  exit(1)
203  finally:
204  pass
205 
206  # RECEIVE message length bytes from FPGA
207  # ---------------------------------------
208  currRxByteCnt = 0
209  nonBlockingTrials = 0
210  while currRxByteCnt < size:
211  try:
212  data = serverSock.recv(MTU)
213  except IOError as e:
214  # On non blocking connections - when there are no incoming data, error is going to be raised
215  # Some operating systems will indicate that using AGAIN, and some using WOULDBLOCK error code
216  # We are going to check for both - if one of them - that's expected, means no incoming data,
217  # continue as normal. If we got different error code - something happened
218  if e.errno != errno.EAGAIN and e.errno != errno.EWOULDBLOCK:
219  print('[ERROR] Socket reading error: {}'.format(str(e)))
220  exit(1)
221  # We just did not receive anything
222  if nonBlockingTrials > 1000000:
223  print('\n[ERROR] Too many socket read attempts ({:d})'.format(nonBlockingTrials))
224  exit(1)
225  break
226  else:
227  nonBlockingTrials += 1
228  if verbose and (nonBlockingTrials % 100 == 0):
229  # print("[DEBUG] So far we received %d bytes out of %d." % (currRxByteCnt, size))
230  print(".", end="")
231  continue
232  except socket.error as exc:
233  # Any other exception
234  print("[EXCEPTION] Socket error while receiving :: %s" % exc)
235  exit(1)
236  else:
237  currRxByteCnt += len(data)
238  if verbose:
239  print("[INFO] ReqBytes=%d | RxBytes=%d\n" % (size, len(data)))
240  print("RxData=%s\n" % data)
241  # [FIXME-TODO: assess the stream of received bytes]
242  nonBlockingTrials = 0
243  finally:
244  pass
245  totalReceivedBytes += currRxByteCnt
246 
247  endTime = datetime.datetime.now()
248  elapseTime = endTime - startTime
249 
250  if totalReceivedBytes < 1000000:
251  print("[INFO] Received a total of %d bytes." % totalReceivedBytes)
252  elif totalReceivedBytes < 1000000000:
253  megaBytes = (totalReceivedBytes * 1.0) / (1024 * 1024 * 1.0)
254  print("[INFO] Received a total of %.1f MB." % megaBytes)
255  else:
256  gigaBytes = (totalReceivedBytes * 1.0) / (1024 * 1024 * 1024 * 1.0)
257  print("[INFO] Transferred a total of %.1f GB." % gigaBytes)
258 
259  bandwidth = (totalReceivedBytes * 8 * 1.0) / (elapseTime.total_seconds() * 1024 * 1024)
260  print("#####################################################")
261  if bandwidth < 1000:
262  print("#### TCP Rx DONE with bandwidth = %6.1f Mb/s" % bandwidth)
263  else:
264  bandwidth = bandwidth / 1000
265  print("#### TCP Rx DONE with bandwidth = %2.1f Gb/s" % bandwidth)
266  if totalReceivedBytes != (end-start+1)*(start+end)/2:
267  print("#### [WARNING] TCP data loss = %.1f%%" % (100 - (totalReceivedBytes) / (size * count)))
268  print("#####################################################")
269  print()
270 
271 
def tcp_rx_ramp(clientSock, serverSock, ip_da, tcp_dp, verbose=False, start=1, end=0xFFFF)
Definition: tc_TcpRecv.py:156

Variable Documentation

◆ action

tc_TcpRecv.action

Definition at line 299 of file tc_TcpRecv.py.

◆ args

tc_TcpRecv.args = parser.parse_args()

Definition at line 302 of file tc_TcpRecv.py.

◆ count

tc_TcpRecv.count = args.loop_count

Definition at line 474 of file tc_TcpRecv.py.

◆ default

tc_TcpRecv.default

Definition at line 281 of file tc_TcpRecv.py.

◆ dpHost

int tc_TcpRecv.dpHost = 2718

Definition at line 385 of file tc_TcpRecv.py.

◆ fpgaClientAssociation

tc_TcpRecv.fpgaClientAssociation

Definition at line 441 of file tc_TcpRecv.py.

◆ fpgaServerAssociation

tuple tc_TcpRecv.fpgaServerAssociation = (str(ipFpga), portFpgaServer)

Definition at line 338 of file tc_TcpRecv.py.

◆ help

tc_TcpRecv.help

Definition at line 282 of file tc_TcpRecv.py.

◆ hostListenAssociation

tuple tc_TcpRecv.hostListenAssociation = (str(ipHostStr), dpHost)

Definition at line 386 of file tc_TcpRecv.py.

◆ hostname

tc_TcpRecv.hostname = socket.gethostname()

Definition at line 366 of file tc_TcpRecv.py.

◆ instId

tc_TcpRecv.instId = getInstanceId(args)

Definition at line 314 of file tc_TcpRecv.py.

◆ int

tc_TcpRecv.int

Definition at line 283 of file tc_TcpRecv.py.

◆ ip4Str

tc_TcpRecv.ip4Str = ni.ifaddresses(itf)[AF_INET][0]['addr']

Definition at line 373 of file tc_TcpRecv.py.

◆ ipFpga

tc_TcpRecv.ipFpga = getFpgaIpv4(args)

Definition at line 310 of file tc_TcpRecv.py.

◆ ipHost

tc_TcpRecv.ipHost = int(ipaddress.IPv4Address(ipHostStr))

Definition at line 382 of file tc_TcpRecv.py.

◆ ipHostStr

string tc_TcpRecv.ipHostStr = socket.gethostbyname(hostname)

Definition at line 367 of file tc_TcpRecv.py.

◆ ipResMngr

tc_TcpRecv.ipResMngr = getResourceManagerIpv4(args)

Definition at line 318 of file tc_TcpRecv.py.

◆ parser

tc_TcpRecv.parser = argparse.ArgumentParser(description='A script to receive TCP data from an FPGA module.')
                                        #

MAIN # #

Definition at line 280 of file tc_TcpRecv.py.

◆ portFpgaServer

tc_TcpRecv.portFpgaServer = XMIT_MODE_LSN_PORT

Definition at line 322 of file tc_TcpRecv.py.

◆ portResMngr

tc_TcpRecv.portResMngr = getResourceManagerPort(args)

Definition at line 326 of file tc_TcpRecv.py.

◆ reqMsgAsBytes

tc_TcpRecv.reqMsgAsBytes = struct.pack(">IHH", ipHost, dpHost, 0)

Definition at line 419 of file tc_TcpRecv.py.

◆ seed

tc_TcpRecv.seed = args.seed

Definition at line 456 of file tc_TcpRecv.py.

◆ size

tc_TcpRecv.size = args.size

Definition at line 464 of file tc_TcpRecv.py.

◆ str

tc_TcpRecv.str

Definition at line 281 of file tc_TcpRecv.py.

◆ tcpClientSock

tc_TcpRecv.tcpClientSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

Definition at line 343 of file tc_TcpRecv.py.

◆ tcpListenSock

tc_TcpRecv.tcpListenSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

Definition at line 392 of file tc_TcpRecv.py.

◆ tcpServerSock

tc_TcpRecv.tcpServerSock

Definition at line 441 of file tc_TcpRecv.py.

◆ TODO_MAX_SEG_SIZE

int tc_TcpRecv.TODO_MAX_SEG_SIZE = 2048

Definition at line 463 of file tc_TcpRecv.py.

◆ type

tc_TcpRecv.type

Definition at line 281 of file tc_TcpRecv.py.

◆ verbose

tc_TcpRecv.verbose = args.verbose

Definition at line 478 of file tc_TcpRecv.py.