私はソケットが初めてで、アプリが機能していないようです。私がやりたいことは、ログ ファイルを Netduino+2 からラップトップに送り返すことです。私が取ったアプローチは、送信する前にファイルサイズをバイト配列に追加することでした。ただし、送信したものを正確に受信することはないようです。これは、ソケットを初めて使用する人にとって非常に一般的な問題であることを認識しており、この問題を回避する方法に関するヒントを見つけるために、高低を検索しました。これはマイクロフレームワーク特有のものなのかもしれませんが、ちょっと疑問です。
これが私のコードです。N+2 で実行されるクライアント アプリと、ラップトップで実行されるコンソール アプリがあります。私が取得しているデータファイルは以下に添付されています。この種の機能はありますが、ファイルを一貫して配信していません。あなたが私に与えることができる助けをいただければ幸いです。
N+2 で実行されるクライアント アプリ。オンボード ボタンを押すと、ファイルが送信されます。
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;
namespace SocketClient
{
public class Program
{
static string strDeviceIP = "";
static string strDeviceSubnet = "";
static string strDeviceGateway = "";
static string strDevicePort = "";
static string strControllerIP = "";
public static OutputPort opLED = new OutputPort(Pins.GPIO_PIN_D13, false);
InputPort button = new InputPort(Pins.ONBOARD_SW1, false, Port.ResistorMode.Disabled);
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,
Port.ResistorMode.Disabled, Port.InterruptMode.InterruptEdgeLow);
btn.OnInterrupt += new NativeEventHandler(ButtonPress);
while (true)
{
}
}
public static void ButtonPress(uint data1, uint data2, DateTime time)
{
opLED.Write(true);
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream,
ProtocolType.Tcp);
IPAddress hostAddress = IPAddress.Parse(strControllerIP);
IPEndPoint endpoint = new IPEndPoint(hostAddress, Int32.Parse(strDevicePort));
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];
// check to make sure it's not too big
if (data.Length > 850 * 1024)
{
Debug.Print("File too large");
}
// 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);
// prepend the size into the senddata array
sizeinfo.CopyTo(senddata, 0);
// copy read data into the senddata array
data.CopyTo(senddata, 4);
// send the data
socket.Connect(endpoint);
socket.Send(senddata);
socket.Close();
opLED.Write(false);
}
}
}
これが私のサーバー側コンソールアプリです。
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;
namespace SocketConsole
{
class Program
{
static void Main(string[] args)
{
Thread thread1 = new Thread(new ThreadStart(Listener));
thread1.Start();
while (true)
{
}
}
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();
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];
//read the size of the message into sizeinfo
int totalread = 0, currentread = 0;
currentread = totalread = client.Receive(sizeinfo, 4,
SocketFlags.None);
while (totalread < sizeinfo.Length && currentread > 0)
{
currentread = client.Receive(sizeinfo, totalread,
sizeinfo.Length - totalread, SocketFlags.None);
totalread += currentread;
}
int messagesize = 0;
messagesize |= sizeinfo[0];
messagesize |= (((int)sizeinfo[1]) << 8);
messagesize |= (((int)sizeinfo[2]) << 16);
messagesize |= (((int)sizeinfo[3]) << 24);
byte[] data = new byte[messagesize];
totalread = 0;
currentread = totalread = client.Receive(data, 0, data.Length -
totalread, SocketFlags.None);
var received = Encoding.UTF8.GetChars(data);
int diff = data.Length - totalread;
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);
BinaryWriter bWrite = new BinaryWriter(File.Open(fName,
FileMode.Create));
bWrite.Write(data);
bWrite.Close();
}
}
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
// socket polling
static bool SocketConnected(Socket s, int ms)
{
return !(s.Poll(ms, SelectMode.SelectRead) & (s.Available == 0));
}
}
}
バイト配列データを見ると、すべてのデータを受信した後、255 を超えるすべてのバイトの値が 0 になります。まるで 255 で読み取りを停止するかのようです。「データ」を埋める while ループで debug.print すると、次のようになります。次の出力:
client accepting data
client.Receive sizeinfo: currentread = 4, totalread = 4
total message size = 3296
client.Receive data: currentread = 252, totalread = 252
client.Receive data: currentread = 256 totalread = 508
client.Receive data: currentread = 256 totalread = 764
client.Receive data: currentread = 256 totalread = 1020
client.Receive data: currentread = 256 totalread = 1276
client.Receive data: currentread = 256 totalread = 1532
client.Receive data: currentread = 256 totalread = 1788
client.Receive data: currentread = 256 totalread = 2044
client.Receive data: currentread = 256 totalread = 2300
client.Receive data: currentread = 256 totalread = 2556
client.Receive data: currentread = 256 totalread = 2812
client.Receive data: currentread = 256 totalread = 3068
client.Receive data: currentread = 228 totalread = 3296
client.Receive data final: currentread = 228 totalread = 3296
そのため、毎回 256 バイトを受け入れていますが、それらはすべてゼロです。明らかに、私は何が起こっているのか理解していません:(