2012-01-12 2 views
1

Эта тривиальная адаптация образца Pachube для Netduino не работает. Это не баф, он просто терпит неудачу. Я заметил, что если вы подождите немного после записи, сокет сообщает 315 байт в свой Available свойство, но попытка прочитать данные просто не работает - cb содержит нуль, а неизменный буфер согласен.Невозможно прочитать из гнезда NETMF

Почему я не могу прочитать эти данные? Я подозреваю, что это ответ сервера, который может помочь мне понять, что не так с остальной частью приложения.

Вот код:

using System; 
using System.Net; 
using System.Net.Sockets; 
using System.Text; 
using System.Threading; 
using Microsoft.SPOT; 
using Microsoft.SPOT.Hardware; 
using SecretLabs.NETMF.Hardware.NetduinoPlus; 
using SecretLabs.NETMF.Hardware; 

public class HelloPachubeSockets 
{ 
    static string apiKey = "wggHejZTKTvE6ZplSc5feSs1rQLeD4cYmi7WPYiG0VLIx_TC-isp8CI9vkKq3nQxadhydl3gUiSK8vS5SBd9JCCoXQG-g0N8FXYlYcNjEfJVMQJA-usgijpE1LRT-xw5"; 
    static string feedId = "43974"; 
    static double maxVoltage = 3.3; 
    static int maxAdcValue = 1023; 
    static int interval = 20000; 
    static Socket connection = null; 
    static Timer timer; 
    static AnalogInput voltagePort; 
    static OutputPort lowPort, highPort; 
    static IPEndPoint remoteEndPoint; 
    static double V = 0; 

    static void LogSensor(object state) 
    { 
     Debug.Print("time: " + DateTime.Now); 
     Debug.Print("memory available: " + Debug.GC(true)); 
     try 
     { 
      connection = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
      connection.SendTimeout = interval/2; 
      connection.Connect(remoteEndPoint); 
      int rawValue = voltagePort.Read(); 
      double value = (rawValue * maxVoltage)/maxAdcValue; 
      string sample = "voltage," + V.ToString("f"); 
      V += 0.1; 
      Debug.Print("new message: " + sample); 
      byte[] contentBuffer = Encoding.UTF8.GetBytes(sample); 
      const string CRLF = "\r\n"; 
      var requestLine = "PUT /v2/feeds/" + feedId + ".csv HTTP/1.1\r\n"; 
      byte[] requestLineBuffer = Encoding.UTF8.GetBytes(requestLine); 
      var headers = 
       "Host: api.pachube.com\r\n" + 
       "X-PachubeApiKey: " + apiKey + CRLF + 
       "Content­Type: text/csv\r\n" + 
       "Content­Length: " + contentBuffer.Length + CRLF + 
       CRLF; 
      byte[] headersBuffer = Encoding.UTF8.GetBytes(headers); 
      connection.Send(requestLineBuffer); 
      connection.Send(headersBuffer); 
      connection.Send(contentBuffer); 
      Thread.Sleep(400); 
      int a = connection.Available; 
      byte[] r = new byte[a]; 
      int cb = connection.Receive(r, 0, a, SocketFlags.None); 
      connection.Close(); 
     } 
     catch 
     { 
      Debug.Print("connection failed"); 
     } 
    } 

    public static void Main() 
    { 
     voltagePort = new AnalogInput(Pins.GPIO_PIN_A1); 
     lowPort = new OutputPort(Pins.GPIO_PIN_A0, false); 
     highPort = new OutputPort(Pins.GPIO_PIN_A2, true); 
     remoteEndPoint = new IPEndPoint(Dns.GetHostEntry("api.pachube.com").AddressList[0], 80); 
     timer = new Timer(LogSensor, null, 0, interval); 
     Thread.Sleep(Timeout.Infinite); 
    } 
} 

Что касается действия ключа Pachube, я проверил с cURL и ключ и подающие детали правильно.

+0

это C# /. NET, если я не ошибаюсь ... может быть, вам стоит попробовать сначала запустить хост-программу C# или C++ на Arduino + Ethernet Shield? Думаю, вам нужно снова пометить и C#;) – errordeveloper

+0

Могу ли я предложить либо попробовать либо использовать HTTP-класс, либо простые TCP-сокеты, которые предоставляет Pachube! – errordeveloper

+0

Тот факт, что это C# /. Net, неявна в теге netduino. Я до сих пор не понял, почему * этот * код не работает, но у меня * есть некоторый более продвинутый код, который работает. Когда мне приходит в голову, что проблема здесь, я напишу (если никто не отвечает первым). –

ответ

0

Если вы ищете http://msdn.microsoft.com/en-us/library/w3xtz6a5.aspx#Y0, вам не нужно будет спать, чтобы дождаться ответа на сокет, так как Receive - это операция блокировки, если буфер пуст.

Что делать, если вы пробовали упрощая Получить код что-то вроде:

// Blocks until send returns. 
connection.Send(...) 

// Get reply from the server. 
int byteCount = server.Receive(bytes, 0, connection.Available, 
           SocketFlags.None); 

if (byteCount > 0) 
    Console.WriteLine(Encoding.UTF8.GetString(bytes)); 

В качестве альтернативы, вы можете явно пытаться что-то вроде 256 байт выходных сокета чтения, вместо доступного номера.

+0

Вы правы, но не по той причине, о которой думаете. Это кросс-нить и переписывание ее по-своему заставляет проблему уйти. Я не знаю, о чем я думал, когда писал этот ужасный код. –

Смежные вопросы