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

Functions

def tcp_tx (sock, message, count, verbose=False)
 
def tcp_rx (sock, message, count, verbose)
 
def waitUntilSocketPairCanBeReused (ipFpga, portFpga)
 
def tcp_txrx_loop (sock, message, count, verbose=False)
 
def tcp_txrx_ramp (sock, message, count, verbose=False)
 

Variables

string gEchoRxPath = './echoRx.dat'
 
string gEchoTxPath = './echoTx.dat'
 
int rc = 0
 
 parser = argparse.ArgumentParser(description='A script to send/receive TCP data to/from an FPGA module.')
 
 type
 
 str
 
 default
 
 help
 
 int
 
 action
 
 args = parser.parse_args()
 
 ipFpga = getFpgaIpv4(args)
 
 instId = getInstanceId(args)
 
 ipResMngr = getResourceManagerIpv4(args)
 
 portFpga = getFpgaPort(args)
 
 portResMngr = getResourceManagerPort(args)
 
int tcpDP = 8803
 
tuple fpgaAssociation = (str(ipFpga), tcpDP)
 
int tcpSP = tcpDP + 49152
 
tuple hostAssociation = (ipSaStr, tcpSP)
 
 tcpSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 
 seed = args.seed
 
 size = args.size
 
 count = args.loop_count
 
 message = str_static_gen(size)
 
 verbose = args.verbose
 
 tx_thread = threading.Thread(target=tcp_tx, args=(tcpSock, message, count, args.verbose))
 
 rx_thread = threading.Thread(target=tcp_rx, args=(tcpSock, message, count, args.verbose))
 
 result = filecmp.cmp(gEchoTxPath, gEchoRxPath, shallow=False)
 

Function Documentation

◆ tcp_rx()

def tc_TcpEcho.tcp_rx (   sock,
  message,
  count,
  verbose 
)
TCP Rx Thread.
 :param sock,       the socket to receive from.
 :param message,    the expected string message to be received.
 :param count,      the number of segment to receive.
 :param verbose,    enables verbosity.
 :return None

Definition at line 89 of file tc_TcpEcho.py.

89 def tcp_rx(sock, message, count, verbose):
90  """TCP Rx Thread.
91  :param sock, the socket to receive from.
92  :param message, the expected string message to be received.
93  :param count, the number of segment to receive.
94  :param verbose, enables verbosity.
95  :return None"""
96 
97  # Create an Rx Test File
98  echoRxFile = open(gEchoRxPath, 'w')
99 
100  # Start Data Reception
101  loop = 0
102  rxBytes = 0
103  expectedBytes = count*len(message)
104  startTime = datetime.datetime.now()
105  while rxBytes < expectedBytes:
106  try:
107  data = sock.recv(expectedBytes - rxBytes)
108  rxBytes += len(data)
109  if count <= 1000:
110  echoRxFile.write(data.decode('ascii'))
111  except socket.error as exc:
112  print("[EXCEPTION] Socket error while receiving :: %s" % exc)
113  else:
114  if verbose:
115  print("Loop=%d | RxBytes=%d" % (loop, rxBytes))
116  loop += 1
117  endTime = datetime.datetime.now()
118  elapseTime = endTime - startTime
119  bandwidth = len(message) * 8 * count * 1.0 / (elapseTime.total_seconds() * 1024 * 1024)
120  print("##################################################")
121  print("#### TCP RX DONE with bandwidth = %6.1f Mb/s ####" % bandwidth)
122  print("##################################################")
123  print()
124 
125  # Close the Rx Test File
126  echoRxFile.close()
127 
128 
def tcp_rx(sock, message, count, verbose)
Definition: tc_TcpEcho.py:89

◆ tcp_tx()

def tc_TcpEcho.tcp_tx (   sock,
  message,
  count,
  verbose = False 
)
TCP Tx Thread.
:param sock,       the socket to send to.
:param message,    the random string to sent.
:param count,      the number of segments to send.
:param verbose,    enables verbosity.
:return None

Definition at line 44 of file tc_TcpEcho.py.

44 def tcp_tx(sock, message, count, verbose=False):
45  """TCP Tx Thread.
46  :param sock, the socket to send to.
47  :param message, the random string to sent.
48  :param count, the number of segments to send.
49  :param verbose, enables verbosity.
50  :return None"""
51  if verbose:
52  print("The following message of %d bytes will be sent out %d times:\n Message=%s\n" %
53  (len(message), count, message.decode('ascii')))
54 
55  # Create a Tx Reference File
56  echoTxFile = open(gEchoTxPath, 'w')
57  if count <= 1000:
58  loop = 0
59  while loop < count:
60  echoTxFile.write(message.decode('ascii'))
61  loop += 1
62 
63  # Start Data Transmission
64  loop = 0
65  startTime = datetime.datetime.now()
66  while loop < count:
67  try:
68  sock.sendall(message)
69  finally:
70  pass
71  loop += 1
72  endTime = datetime.datetime.now()
73  elapseTime = endTime - startTime;
74  bandwidth = len(message) * 8 * count * 1.0 / (elapseTime.total_seconds() * 1024 * 1024)
75  print("##################################################")
76  print("#### TCP TX DONE with bandwidth = %6.1f Mb/s ####" % bandwidth)
77  print("##################################################")
78  print()
79 
80  # Close the Tx Reference File
81  echoTxFile.close()
82  # Push a few more bytes to force the FPGA to flush its buffers
83  try:
84  sock.sendall(message)
85  finally:
86  pass
87 
88 
def tcp_tx(sock, message, count, verbose=False)
Definition: tc_TcpEcho.py:44

◆ tcp_txrx_loop()

def tc_TcpEcho.tcp_txrx_loop (   sock,
  message,
  count,
  verbose = False 
)
TCP Tx-Rx Single-Thread Loop.
 :param sock     The socket to send/receive to/from.
 :param message  The message string to sent.
 :param count    The number of segments send.
 :param verbose  Enables verbosity.
 :return         None

Definition at line 153 of file tc_TcpEcho.py.

153 def tcp_txrx_loop(sock, message, count, verbose=False):
154  """TCP Tx-Rx Single-Thread Loop.
155  :param sock The socket to send/receive to/from.
156  :param message The message string to sent.
157  :param count The number of segments send.
158  :param verbose Enables verbosity.
159  :return None"""
160  if verbose:
161  print("[INFO] The following message of %d bytes will be sent out %d times:\n Message=%s\n" %
162  (len(message), count, message.decode('ascii')))
163  nrErr = 0
164  txMssgCnt = 0
165  rxMssgCnt = 0
166  rxByteCnt = 0
167  txStream = ""
168  rxStream = ""
169 
170  # Init the Tx reference stream
171  for i in range(count):
172  txStream = txStream + message.decode('ascii')
173 
174  startTime = datetime.datetime.now()
175 
176  while rxByteCnt < (count * len(message)):
177  if txMssgCnt < count:
178  # Send a new message
179  # ------------------------
180  try:
181  tcpSock.sendall(message)
182  txMssgCnt += 1
183  finally:
184  pass
185 
186  # Receive a segment
187  # --------------------
188  try:
189  data = tcpSock.recv(len(message))
190  rxByteCnt += len(data)
191  rxMssgCnt += 1
192  if verbose:
193  print("%d:%s" % (rxMssgCnt, data.decode('ascii')))
194  except IOError as e:
195  # On non blocking connections - when there are no incoming data, error is going to be
196  # raised. Some operating systems will indicate that using AGAIN, and some using
197  # WOULDBLOCK error code. We are going to check for both - if one of them - that's
198  # expected, means no incoming data, continue as normal. If we got different error code,
199  # something happened
200  if e.errno != errno.EAGAIN and e.errno != errno.EWOULDBLOCK:
201  print('[ERROR] Socket reading error: {}'.format(str(e)))
202  exit(1)
203  # We just did not receive anything
204  continue
205  except socket.error as exc:
206  # Any other exception
207  print("[EXCEPTION] Socket error while receiving :: %s" % exc)
208  # exit(1)
209  finally:
210  pass
211  rxStream = rxStream + data.decode('ascii')
212 
213  endTime = datetime.datetime.now()
214 
215  if verbose:
216  print("\n")
217 
218  # Compare Tx and Rx stream
219  if rxStream != txStream:
220  print(" KO | Received stream = %s" % data.decode('ascii'))
221  print(" | Expected stream = %s" % rxStream)
222  nrErr += 1
223  elif verbose:
224  print(" OK | Received %d bytes in %d messages." % (rxByteCnt, rxMssgCnt))
225 
226  elapseTime = endTime - startTime;
227  bandwidth = len(message) * 8 * count * 1.0 / (elapseTime.total_seconds() * 1024 * 1024)
228  print("[INFO] Transferred a total of %d bytes." % rxByteCnt)
229  print("#####################################################")
230  print("#### TCP Tx/Rx DONE with bandwidth = %6.1f Mb/s ####" % bandwidth)
231  print("#####################################################")
232  print()
233 
def tcp_txrx_loop(sock, message, count, verbose=False)
Definition: tc_TcpEcho.py:153

◆ tcp_txrx_ramp()

def tc_TcpEcho.tcp_txrx_ramp (   sock,
  message,
  count,
  verbose = False 
)
TCP Tx-Rx Single-Thread Ramp.
 :param sock     The socket to send/receive to/from.
 :param message  The message string to sent.
 :param count    The number of segments to send.
 :param verbose  Enables verbosity.
 :return         None

Definition at line 234 of file tc_TcpEcho.py.

234 def tcp_txrx_ramp(sock, message, count, verbose=False):
235  """TCP Tx-Rx Single-Thread Ramp.
236  :param sock The socket to send/receive to/from.
237  :param message The message string to sent.
238  :param count The number of segments to send.
239  :param verbose Enables verbosity.
240  :return None"""
241  if verbose:
242  print("[INFO] The following message of %d bytes will be sent out incrementally %d times:\n Message=%s\n" %
243  (len(message), count, message.decode('ascii')))
244  nrErr = 0
245  loop = 0
246  rxByteCnt = 0
247  startTime = datetime.datetime.now()
248  while loop < count:
249  i = 1
250  while i <= len(message):
251  subMsg = message[0:i]
252  # Send datagram
253  # -------------------
254  try:
255  tcpSock.sendall(subMsg)
256  finally:
257  pass
258  # Receive datagram
259  # -------------------
260  try:
261  data = tcpSock.recv(len(subMsg))
262  rxByteCnt += len(data)
263  if data == subMsg:
264  if verbose:
265  print("Loop=%d | RxBytes=%d" % (loop, len(data)))
266  else:
267  print("Loop=%d | RxBytes=%d" % (loop, len(data)))
268  print(" KO | Received Message=%s" % data.decode('ascii'))
269  print(" | Expecting Message=%s" % subMsg)
270  nrErr += 1
271  except IOError as e:
272  # On non blocking connections - when there are no incoming data, error is going to be raised
273  # Some operating systems will indicate that using AGAIN, and some using WOULDBLOCK error code
274  # We are going to check for both - if one of them - that's expected, means no incoming data,
275  # continue as normal. If we got different error code - something happened
276  if e.errno != errno.EAGAIN and e.errno != errno.EWOULDBLOCK:
277  print('[ERROR] Socket reading error: {}'.format(str(e)))
278  exit(1)
279  # We just did not receive anything
280  continue
281  except socket.error as exc:
282  # Any other exception
283  print("[EXCEPTION] Socket error while receiving :: %s" % exc)
284  # exit(1)
285  finally:
286  pass
287  i += 1
288  loop += 1
289  endTime = datetime.datetime.now()
290  elapseTime = endTime - startTime
291  bandwidth = (rxByteCnt * 8 * count * 1.0) / (elapseTime.total_seconds() * 1024 * 1024)
292  megaBytes = (rxByteCnt * 1.0) / (1024 * 1024 * 1.0)
293  print("[INFO] Transferred a total of %.1f MB." % megaBytes)
294  print("#####################################################")
295  print("#### TCP Tx/Rx DONE with bandwidth = %6.1f Mb/s ####" % bandwidth)
296  print("#####################################################")
297  print()
298 
299 
def tcp_txrx_ramp(sock, message, count, verbose=False)
Definition: tc_TcpEcho.py:234

◆ waitUntilSocketPairCanBeReused()

def tc_TcpEcho.waitUntilSocketPairCanBeReused (   ipFpga,
  portFpga 
)
Check and wait until the a socket pair can be reused.
    [INFO] When a client or a server initiates an active close, then the same destination socket
      (i.e. the same IP address / TCP port number) cannot be re-used immediately because
      of security issues. Therefore, a closed connection must linger in a 'TIME_WAIT' or
      'FIN_WAIT' state for as long as 2xMSL (Maximum Segment Lifetime), which corresponds
      to twice the time a TCP segment might exist in the internet system. The MSL is
      arbitrarily defined to be 2 minutes long.
:param ipFpga:   the IP address of FPGA.
:param portFpga: the TCP port of the FPGA.
:return: nothing

Definition at line 129 of file tc_TcpEcho.py.

129 def waitUntilSocketPairCanBeReused(ipFpga, portFpga):
130  """Check and wait until the a socket pair can be reused.
131  [INFO] When a client or a server initiates an active close, then the same destination socket
132  (i.e. the same IP address / TCP port number) cannot be re-used immediately because
133  of security issues. Therefore, a closed connection must linger in a 'TIME_WAIT' or
134  'FIN_WAIT' state for as long as 2xMSL (Maximum Segment Lifetime), which corresponds
135  to twice the time a TCP segment might exist in the internet system. The MSL is
136  arbitrarily defined to be 2 minutes long.
137  :param ipFpga: the IP address of FPGA.
138  :param portFpga: the TCP port of the FPGA.
139  :return: nothing
140  """
141  wait = True
142  # NETSTAT example: rc = os.system("netstat | grep '10.12.200.163:8803' | grep TIME_WAIT")
143  cmdStr = "netstat | grep \'" + str(ipFpga) + ":" + str(portFpga) + "\' | grep \'TIME_WAIT\|FIN_WAIT\' "
144  while wait:
145  rc = os.system(cmdStr)
146  if rc == 0:
147  print("[INFO] Cannot reuse this socket as long as it is in the \'TIME_WAIT\' or \'FIN_WAIT\' state.")
148  print(" Let's sleep for 5 sec...")
149  time.sleep(5)
150  else:
151  wait = False
152 
def waitUntilSocketPairCanBeReused(ipFpga, portFpga)
Definition: tc_TcpEcho.py:129

Variable Documentation

◆ action

tc_TcpEcho.action

Definition at line 322 of file tc_TcpEcho.py.

◆ args

tc_TcpEcho.args = parser.parse_args()

Definition at line 335 of file tc_TcpEcho.py.

◆ count

tc_TcpEcho.count = args.loop_count

Definition at line 449 of file tc_TcpEcho.py.

◆ default

tc_TcpEcho.default

Definition at line 310 of file tc_TcpEcho.py.

◆ fpgaAssociation

tuple tc_TcpEcho.fpgaAssociation = (str(ipFpga), tcpDP)

Definition at line 377 of file tc_TcpEcho.py.

◆ gEchoRxPath

string tc_TcpEcho.gEchoRxPath = './echoRx.dat'

Definition at line 41 of file tc_TcpEcho.py.

◆ gEchoTxPath

string tc_TcpEcho.gEchoTxPath = './echoTx.dat'

Definition at line 42 of file tc_TcpEcho.py.

◆ help

tc_TcpEcho.help

Definition at line 311 of file tc_TcpEcho.py.

◆ hostAssociation

tuple tc_TcpEcho.hostAssociation = (ipSaStr, tcpSP)

Definition at line 389 of file tc_TcpEcho.py.

◆ instId

tc_TcpEcho.instId = getInstanceId(args)

Definition at line 347 of file tc_TcpEcho.py.

◆ int

tc_TcpEcho.int

Definition at line 312 of file tc_TcpEcho.py.

◆ ipFpga

tc_TcpEcho.ipFpga = getFpgaIpv4(args)

Definition at line 343 of file tc_TcpEcho.py.

◆ ipResMngr

tc_TcpEcho.ipResMngr = getResourceManagerIpv4(args)

Definition at line 351 of file tc_TcpEcho.py.

◆ message

tc_TcpEcho.message = str_static_gen(size)

Definition at line 453 of file tc_TcpEcho.py.

◆ parser

tc_TcpEcho.parser = argparse.ArgumentParser(description='A script to send/receive TCP data to/from an FPGA module.')

Definition at line 309 of file tc_TcpEcho.py.

◆ portFpga

tc_TcpEcho.portFpga = getFpgaPort(args)

Definition at line 355 of file tc_TcpEcho.py.

◆ portResMngr

tc_TcpEcho.portResMngr = getResourceManagerPort(args)

Definition at line 359 of file tc_TcpEcho.py.

◆ rc

int tc_TcpEcho.rc = 0
                                        #

MAIN # #

Definition at line 305 of file tc_TcpEcho.py.

◆ result

tc_TcpEcho.result = filecmp.cmp(gEchoTxPath, gEchoRxPath, shallow=False)

Definition at line 476 of file tc_TcpEcho.py.

◆ rx_thread

tc_TcpEcho.rx_thread = threading.Thread(target=tcp_rx, args=(tcpSock, message, count, args.verbose))

Definition at line 465 of file tc_TcpEcho.py.

◆ seed

tc_TcpEcho.seed = args.seed

Definition at line 434 of file tc_TcpEcho.py.

◆ size

tc_TcpEcho.size = args.size

Definition at line 440 of file tc_TcpEcho.py.

◆ str

tc_TcpEcho.str

Definition at line 310 of file tc_TcpEcho.py.

◆ tcpDP

int tc_TcpEcho.tcpDP = 8803

Definition at line 376 of file tc_TcpEcho.py.

◆ tcpSock

tc_TcpEcho.tcpSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

Definition at line 399 of file tc_TcpEcho.py.

◆ tcpSP

int tc_TcpEcho.tcpSP = tcpDP + 49152

Definition at line 388 of file tc_TcpEcho.py.

◆ tx_thread

tc_TcpEcho.tx_thread = threading.Thread(target=tcp_tx, args=(tcpSock, message, count, args.verbose))

Definition at line 464 of file tc_TcpEcho.py.

◆ type

tc_TcpEcho.type

Definition at line 310 of file tc_TcpEcho.py.

◆ verbose

tc_TcpEcho.verbose = args.verbose

Definition at line 457 of file tc_TcpEcho.py.