Important changes to forums and questions
All forums and questions are now archived. To start a new conversation or read the latest updates go to forums.mbed.com.
9 years, 9 months ago.
EthernetInterface hangs
I have two FRDM-K64F boards talking to each other using TCP. One is a server, and one is a client. The code is based on the testbench code found in the link: http://developer.mbed.org/users/emilmont/notebook/networking-libraries-benchmark/
The client connects and disconnects from the server many times to test the data throughput and ability to connect/disconnect. Sometimes the server hangs on line 55. It is stuck waiting for something and I'm not sure what. So I wrote a client in python so I could test the server that way. When using the python client, the server has only frozen once. I've had the python run probably 50k test cycles (connect, transmit/receive, disconnect) and it only froze once. The c++ client on the FRDM board freezes about 1 in 100 test cycles and it always freezes on line 55.
Does anyone have any idea why this would be freezing for the FRDM client but not the python client? I've tried inserting time delays at different points to slow down either the server or client but that doesn't seem to help. I thought that maybe the FRDM client runs faster than my laptop and that was causing the issue.
I published both the server and client code and they can be found at the following links:
http://developer.mbed.org/users/timmey9/code/Test_Tcp_Client/
http://developer.mbed.org/users/timmey9/code/Test_Tcp_Server/
Note: The client code has a switch statement for trying different things and debugging. The actual test is under case 'L'.
TCP Server
#include "mbed.h" #include "EthernetInterface.h" #define ECHO_SERVER_PORT 54321 #define IP "169.254.225.206" #define GATEWAY "169.254.225.1" #define MASK "255.255.0.0" #define LEN 18980 uint16_t sample_array0[LEN]; DigitalOut led_red(LED_RED); DigitalOut led_green(LED_GREEN); DigitalOut led_blue(LED_BLUE); Serial pc(USBTX,USBRX); int main (void) { for(int i = 0; i < LEN; i++) sample_array0[i] = ((0x0031<<8) | 0x0032); sample_array0[0] = ('S'<<8)|'S'; sample_array0[LEN-1] = ('F'<<8) | 'F'; pc.baud(230400); pc.printf("Starting test server\r\n"); EthernetInterface eth; eth.init(IP, MASK, GATEWAY); eth.connect(); pc.printf("IP Address is %s\r\n", eth.getIPAddress()); TCPSocketServer server; server.bind(ECHO_SERVER_PORT); server.listen(); led_blue = 1; led_green = 1; led_red = 1; while (true) { //pc.printf("\r\nWait for new connection...\r\n"); TCPSocketConnection client; server.accept(client); client.set_blocking(true, 5000); //pc.printf("Connection from: %s\r\n", client.get_address()); char buffer[1460]; // size of IP payload while (true) { int n = client.receive(buffer, sizeof(buffer)); if (n <= 0) break; pc.printf("Rec: %i: ",n); n = client.send_all((char *)sample_array0, LEN*2); if (n <= 0) {led_blue = 0; break;} pc.printf("Sent %i: ",n); } client.close(); pc.printf("\r\n"); } }
TCP Client
#include "mbed.h" #include "EthernetInterface.h" #define PORT 54321 #define LEN_PACKET 1460 #define IP "169.254.225.220" #define GATEWAY "169.254.225.1" #define MASK "255.255.0.0" #define DES_ADDR "169.254.225.206" #define DES_LAPTOP "169.254.225.210" #define LEN 18980 uint16_t sample_array0[LEN]; Serial pc(USBTX,USBRX); int main (void) { for(int i = 0; i < LEN; i++) sample_array0[i] = ((0x0031<<8) | 0x0032); pc.baud(230400); pc.printf("Starting test client\r\n"); EthernetInterface eth; eth.init(IP, MASK, GATEWAY); eth.connect(); pc.printf("IP Address is %s\r\n", eth.getIPAddress()); TCPSocketConnection mallet; mallet.set_blocking(false,5000); char buffer[LEN_PACKET]; for(int i = 0; i < LEN_PACKET; i++) buffer[i] = i; while (true) { if(pc.readable() > 0){ char temp = pc.getc(); int var = 0; switch(temp){ case 'Q': case 'q': var = mallet.connect(DES_LAPTOP,5005); if(var == 0) pc.printf("Connected to laptop successfully\r\n"); else if(var == -1) pc.printf("Connecting failed\r\n"); break; case 'A': case 'a': var = mallet.connect(DES_ADDR,PORT); if(var == 0) pc.printf("Connected to FRDM server successfully\r\n"); else if(var == -1) pc.printf("Connecting failed\r\n"); break; case 'S': case 's': var = mallet.send(buffer,LEN_PACKET); pc.printf("Sent %i bytes\r\n",var); break; case 'D': case 'd': var = mallet.receive_all((char *)sample_array0,LEN*2); pc.printf("Received %i bytes\r\n",var); break; case 'F': case 'f': var = mallet.close(); if(var == 0) pc.printf("Connection closed\r\n"); else pc.printf("Error while closing connection\r\n"); break; case 'Z': case 'z': pc.printf("Status: "); if(mallet.is_connected()) pc.printf("Connected\r\n"); else pc.printf("Not connected\r\n"); break; case 'R': case 'r': // open connection var = mallet.connect(DES_ADDR,PORT); if(var == 0) pc.printf("Connected successfully\r\n"); else if(var == -1) pc.printf("Connection already open\r\n"); // send data var = mallet.send(buffer,LEN_PACKET); pc.printf("Sent %i bytes\r\n",var); // receive data var = mallet.receive_all((char *)sample_array0,LEN*2); pc.printf("Received %i bytes\r\n",var); // closed connection var = mallet.close(); if(var == 0) pc.printf("Connection closed\r\n\n"); else pc.printf("Error while closing connection\r\n\n"); break; case 'L': case 'l': for(int i = 0; i < 1000; i++){ //wait_ms(100); pc.printf("%3i: ",i); // open connection var = mallet.connect(DES_ADDR,PORT); if(var == -1) {i = 50; break;} // send data var = mallet.send(buffer,LEN_PACKET); pc.printf("Sent %i: ",var); if(var == -1) {i = 50; break;} // receive data var = mallet.receive_all((char *)sample_array0,LEN*2); pc.printf("Rec %i: ",var); if(var == -1) {i = 50; break;} // closed connection var = mallet.close(); if(var == -1) {i = 50; break;} pc.printf("\r\n"); } break; } } } }
Python TCP client
import socket import random, string from time import time from time import sleep MAX_SEGMENT_SIZE = 1460 ECHO_SERVER_ADDRESS = "169.254.225.206" ECHO_SERVER_PORT = 54321 N_PACKETS = 40*3*NUM_MALLETS/2 LEN_PACKET = 1460 N_SAMPLES = LEN_PACKET*N_PACKETS # approximately 29200 uint16 * 3 instruments PACKET = ''.join(random.choice(string.ascii_uppercase+string.digits) for _ in range(LEN_PACKET)) UPDATE_STEP = (N_PACKETS/10) bytes = [] times = [] CNT = 3000 total = time() for x in range(CNT): #connect s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((ECHO_SERVER_ADDRESS, ECHO_SERVER_PORT)) #send data start = time() s.sendall(PACKET) #receive response data = s.recv(18980*2) length = len(data) t = time() - start bytes.append(length) times.append(t) #close s.close() if((x%100) == 0): print "{0:3.0f}% ".format(float(x)/float(CNT)*100) total = time()-total print "100%\n" avg_bytes = reduce(lambda x, y: x + y,bytes)/float(len(bytes)) avg_time = reduce(lambda x, y: x + y,times)/float(len(times)) print "Average bytes: {0:f} bytes".format(avg_bytes) print "Average time: {0:f} s".format(avg_time) print "Average receive rate: {0:.3f} MB/s".format(avg_bytes/avg_time/1024/1024) print "Average receive rate: {0:.3f} Mb/s".format(avg_bytes*8/avg_time/1024/1024) print "Overall receive rate: {0:.3f} MB/s".format(avg_bytes*CNT/total/1024/1024)
Hi Joey,
Did you ever find the issue with this? I'd be willing to help investigate.
Thanks, Brian
posted by Brian Daniels 19 May 2015Not really. I just figured out how to avoid it using trial and error. It is probably worth investigating for future reference, but I believe I have sufficiently dodged the problem for my application.
posted by Joey McElderry 21 May 2015Hi Joey, I've replicated the issue that you described for the two mBed's talking over Ethernet.
According to the prints, it looks like it's getting frozen on the server side. The client has a "Sent message" without a receive, and the server has a "receive" message without a sent message. I'll keep investigating
posted by Brian Daniels 21 May 2015