我是套接字新手,似乎无法让我的应用程序正常工作。我想要做的是从 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 个字节,但它们都为零。显然,我不明白发生了什么:(