1

私はソケットが初めてで、アプリが機能していないようです。私がやりたいことは、ログ ファイルを 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 バイトを受け入れていますが、それらはすべてゼロです。明らかに、私は何が起こっているのか理解していません:(

4

1 に答える 1

2

2 番目の while ループで、Receive メソッドを呼び出している間は、次のように使用しています。

currentread = client.Receive(data, 0, data.Length - totalread, SocketFlags.None);

ここでの 2 番目のパラメータは次のことを示します: " The location in buffer to store the received data."

これは、すべての読み取りデータが実際にはすべての古いデータを上書きしていることを意味します。

次のコードに置き換える必要があります。

currentread = client.Receive(data, totalread, data.Length - totalread, SocketFlags.None);

totalreadコード内の変数は常に、新しく受信したデータの新しい場所を指すために使用できる合計読み取りバイト数を保持するためです。

于 2013-07-25T17:14:04.577 に答える