dart-archive / sdk

The Dartino project was an experiment seeking to improve productivity when writing application code for embedded devices.
https://dartino.org
Other
330 stars 36 forks source link

Cannot connect socket after resetting #520

Closed sgjesse closed 8 years ago

sgjesse commented 8 years ago

If I run the sample Dart server in samples/stm32f746g-discovery/http_json_sample_server/http_json_sample_server.dart (IP and port changed - see exception below) I can connect fine from the discovery board. However if I reset the device the connection fails with error -116.

Uncaught exception:
a Instance: 
  - class = class
  - @0 = Can't connect to 192.168.0.100:8081 (-116)

Waiting some time after a successful connect before resetting the device seems to not create the issue.

sgjesse commented 8 years ago

If I restart the Dart server before resetting the device the error does not occur..

sgjesse commented 8 years ago

If resetting after making a lot of connections this does not happen. Maybe it is related to the local port number selected by the FreeRTOS TCP/IP stack.

It could also be an issue with closing the socket. After making many connections using the code below with samples/stm32f746g-discovery/http_json_sample_server/http_json_sample_server.dart and then running netstat reveals a large number of connections in state ESTABLISHED (running on Linux).

// Copyright (c) 2016, the Dartino project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE.md file.

// Demonstrates how to use the ethernet package.

import 'dart:convert';
import 'dart:dartino';

import 'package:http/http.dart';
import 'package:socket/socket.dart';
import 'package:stm32/ethernet.dart';

const String host = "192.168.0.100";
const int port = 8081;
const String path = "/message.json";

main() {
  print('Hello from Dartino');
  if (!ethernet.InitializeNetworkStack(
      const InternetAddress(const <int>[192, 168, 0, 10]),
      const InternetAddress(const <int>[255, 255, 255, 0]),
      const InternetAddress(const <int>[192, 168, 0, 1]),
      const InternetAddress(const <int>[8, 8, 8, 8]))) {
    throw 'Failed to initialize network stack';
  }

  print('Network up, requesting DHCP configuration...');

  int i = 0;
  int sleepInterval = 5000;
  while (NetworkInterface.list().isEmpty) {
    printNetworkInfo();
    sleep(sleepInterval);
    i++;
    print("waited ${i*sleepInterval} ms");
  }

  int requestCount = 0;
  while (true) {
    requestCount++;
    print('Performing request $requestCount');
    Map json = downloadData(host, port, path);
    if (json == null) {
      print('Failed to make HTTP request');
      sleep(1000);
    }
  }
}

void printNetworkInfo() {
  bool eth0Connected = false;
  for (NetworkInterface interface in
      NetworkInterface.list(includeLoopback: true)) {
    print("${interface.name}:");
    for (InternetAddress address in interface.addresses) {
      print("  $address");
    }
    print("  ${interface.isConnected ? 'connected' : 'not connected'}");
    if (interface.name == 'eth0' && interface.isConnected) eth0Connected = true;
  }
}

/// Download a JSON object from the server [host]:[port] at [uri] and return the
/// parsed result as a Dart map.
Map downloadData(String host, int port, String uri) {
  Socket socket;
  try {
    socket = new Socket.connect(host, port);
    HttpConnection https = new HttpConnection(socket);
    HttpRequest request = new HttpRequest(uri);
    request.headers["Host"] = host;
    HttpResponse response = https.send(request);
    if (response.statusCode != HttpStatus.OK) {
      print("Failed to receive document: ${response.statusCode}");
      return null;
    }
    HttpHeaders headers = response.headers;
    String contentType = headers.contentType;
    if (contentType == "application/json") {
      Object result = JSON.decode(new String.fromCharCodes(response.body));
      if (result is! Map) {
        print("Expected a map.");
        return null;
      }
      return result;
    } else {
      print("Expected content of type 'application/json'"
            " but got '$contentType'.");
      return null;
    }
  } on SocketException catch (e) {
    print(e);
    return null;
  } finally {
    socket?.close();
  }
}