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

在第二个 while 循环中,并在调用 Receive 方法时,您是这样使用它的:

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

这里的第二个参数表示:“ 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 回答