I'm new to sockets and just can't seem to get my app working. What I want to do is send a log file from the N+2 back to my laptop. The approach I took was to prepend the file size to the byte array before sending. However, I never seem to receive exactly what I send. I realize this is a very common problem with folks who are new to sockets and I've searched high and low to find tips on how to avoid this problem. Maybe this is something unique to N+2, but I kind of doubt it.
Here is my code. I've got a client app that runs on the N+2 and a console app running on my laptop. The data file I'm retrieving is attached below. This sort of works, but is not delivering the file consistently. Any help you can give me would be appreciated.
Client app running on N+2. When you press the onboard button, it sends the file.
[font="'courier new', courier, monospace;"]using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Text;
using System.IO;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.Netduino;[/font]
[font="'courier new', courier, monospace;"]namespace SocketClient
{[/font]
[font="'courier new', courier, monospace;"] public class Program
{
static string strDeviceIP = "";
static string strDeviceSubnet = "";
static string strDeviceGateway = "";
static string strDevicePort = "";
static string strControllerIP = "";[/font]
[font="'courier new', courier, monospace;"] public static OutputPort opLED = new OutputPort(Pins.GPIO_PIN_D13, false);
InputPort button = new InputPort(Pins.ONBOARD_SW1, false, Port.ResistorMode.Disabled);[/font]
[font="'courier new', courier, monospace;"] public static void Main()
{
strDeviceIP = "192.168.2.102";
strDeviceSubnet = "255.255.255.0";
strDeviceGateway = "192.168.2.2";
strControllerIP = "192.168.2.222";
strDevicePort = "9999";
InterruptPort btn = new InterruptPort(Pins.ONBOARD_SW1, false,[/font]
[font="'courier new', courier, monospace;"]Port.ResistorMode.Disabled, Port.InterruptMode.InterruptEdgeLow);
btn.OnInterrupt += new NativeEventHandler(ButtonPress);[/font]
[font="'courier new', courier, monospace;"] while (true)
{
}
}[/font]
[font="'courier new', courier, monospace;"] public static void ButtonPress(uint data1, uint data2, DateTime time)
{
opLED.Write(true);[/font]
[font="'courier new', courier, monospace;"] Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPAddress hostAddress = IPAddress.Parse(strControllerIP);
IPEndPoint endpoint = new IPEndPoint(hostAddress, Int32.Parse(strDevicePort));[/font]
[font="'courier new', courier, monospace;"] string fileName = "runlog2.txt";
// read the file into a byte array
byte[] data = File.ReadAllBytes(@"SD" + fileName);
byte[] sizeinfo = new byte[4];
byte[] senddata = new byte[4 + data.Length];[/font]
[font="'courier new', courier, monospace;"] // check to make sure it's not too big
if (data.Length > 850 * 1024)
{
Debug.Print("File too large");
}[/font]
[font="'courier new', courier, monospace;"] // convert data.length into a byte array
sizeinfo[0] = (byte)data.Length;
sizeinfo[1] = (byte)(data.Length >> 8);
sizeinfo[2] = (byte)(data.Length >> 16);
sizeinfo[3] = (byte)(data.Length >> 24);[/font]
[font="'courier new', courier, monospace;"] // prepend the size into the senddata array
sizeinfo.CopyTo(senddata, 0);[/font]
[font="'courier new', courier, monospace;"] // copy read data into the senddata array
data.CopyTo(senddata, 4);[/font]
[font="'courier new', courier, monospace;"] // send the data
socket.Connect(endpoint);
socket.Send(senddata);
socket.Close();
opLED.Write(false);
}
}
}[/font]
[font="'courier new', courier, monospace;"]Here is my server side console app.[/font]
[font="'courier new', courier, monospace;"] [/font]
[font="'courier new', courier, monospace;"]using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Collections;
using System.Threading;[/font]
[font="'courier new', courier, monospace;"]namespace SocketConsole
{
class Program
{
static void Main(string[] args)
{
Thread thread1 = new Thread(new ThreadStart(Listener));
thread1.Start();[/font]
[font="'courier new', courier, monospace;"] while (true)
{
}
}[/font]
[font="'courier new', courier, monospace;"] public static void Listener()
{
try
{
Socket sktMain = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
sktMain.Bind(new IPEndPoint(IPAddress.Parse("192.168.2.222"), 9999));
sktMain.Listen(10);
var message = new ArrayList();[/font]
[font="'courier new', courier, monospace;"] while (true)
{
// create the client socket
using (var client = sktMain.Accept())
{
//If connected,
if (SocketConnected(client, 100))
{
while (SocketConnected(client, 100))
{
byte[] sizeinfo = new byte[4];[/font]
[font="'courier new', courier, monospace;"] //read the size of the message into sizeinfo
int totalread = 0, currentread = 0;
currentread = totalread = client.Receive(sizeinfo, 4, SocketFlags.None);[/font]
[font="'courier new', courier, monospace;"] while (totalread < sizeinfo.Length && currentread > 0)
{
currentread = client.Receive(sizeinfo, totalread, sizeinfo.Length - totalread, SocketFlags.None);
totalread += currentread;
}[/font]
[font="'courier new', courier, monospace;"] int messagesize = 0;
messagesize |= sizeinfo[0];
messagesize |= (((int)sizeinfo[1]) << 8);
messagesize |= (((int)sizeinfo[2]) << 16);
messagesize |= (((int)sizeinfo[3]) << 24);[/font]
[font="'courier new', courier, monospace;"] byte[] data = new byte[messagesize];
totalread = 0;
currentread = totalread = client.Receive(data, 0, data.Length - totalread, SocketFlags.None);
var received = Encoding.UTF8.GetChars(data);[/font]
[font="'courier new', courier, monospace;"] int diff = data.Length - totalread;[/font]
[font="'courier new', courier, monospace;"] while (totalread < messagesize && currentread > 0)
{
currentread = client.Receive(data, 0, data.Length - totalread, SocketFlags.None);
totalread += currentread;
for (var i = 0; i < received.Length; i++)
message.Add(received[i]);
}
string fName = "runlog.txt";
if (File.Exists(fName)) File.Delete(fName);[/font]
[font="'courier new', courier, monospace;"] BinaryWriter bWrite = new BinaryWriter(File.Open(fName, FileMode.Create));
bWrite.Write(data);
bWrite.Close();
}
}
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}[/font]
[font="'courier new', courier, monospace;"] // socket polling
static bool SocketConnected(Socket s, int ms)
{
return !(s.Poll(ms, SelectMode.SelectRead) & (s.Available == 0));
}[/font]
[font="'courier new', courier, monospace;"] }
}[/font]