2

嗨,我对 NET 编程很陌生。我必须开发一个应用程序,客户端需要通过 LAN 访问服务器,并从远程 MS ACCESS 数据库接收数据。通信成功,服务器正在发送 XML 格式的数据表。但是,当客户端收到字符串并尝试将其转换为 XML 并填充 datagridview 时,它会给出错误

“十六进制值 0x00 是无效字符”

任何解决此问题的帮助将不胜感激。我同时使用了 ASCII 编码和 UTF-8 编码,但都不起作用。

这是发送请求的客户端

    Dim client As New Net.Sockets.TcpClient
    Dim stream As NetworkStream = Nothing
    sql = "Select * from Roll "

    client.Connect("127.0.0.1", 3000)
    stream = client.GetStream
    Dim sendbytes() As Byte = Encoding.ASCII.GetBytes(sql)
    stream.Write(sendbytes, 0, sendbytes.Length)

然后服务器接收它并在数据库上运行查询并通过 LAN 连接发送数据表

        client = server.AcceptTcpClient
        stream = client.GetStream
        Dim rvcBytes(client.ReceiveBufferSize) As Byte
        stream.Read(rvcBytes, 0, client.ReceiveBufferSize)
        Dim recive As String = Encoding.ASCII.GetString(rvcBytes)


    Try 'lotNumberFrom & " and LotNumber " & lotNumberTo


        cmd = New OleDbCommand(recive, con)
        '  MsgBox(recive)
        ds.Clear()

        adapter.SelectCommand = cmd
        adapter.Fill(ds, "Batch data")

        Dim writer As New System.IO.StringWriter
        ds.Tables("Batch data").WriteXml(writer, True)

        ' MsgBox(writer.ToString)
        Dim sendbytes() As Byte = Encoding.ASCII.GetBytes(writer.ToString)
        stream.Write(sendbytes, 0, sendbytes.Length)





    Catch ex As Exception
        MsgBox(ex.ToString)
    End Try

然后客户端收到它并尝试填充数据网格视图。那就是问题发生的地方。

    Dim rvcBytes(client.ReceiveBufferSize) As Byte
    stream.Read(rvcBytes, 0, client.ReceiveBufferSize)
    Dim recive As String = Encoding.ASCII.GetString(rvcBytes)
    Dim dsa As New DataSet



    dsa.ReadXml(New XmlTextReader(New StringReader(recive)))
    DataGridView1.DataSource = dsa.Tables(0)

    client.Close()
4

1 回答 1

0

我首先尝试调整您的代码,但在搜索信息时,我发现了几个 MSDN 示例:

同步服务器套接字示例
http://msdn.microsoft.com/en-CA/library/6y0e13d3.aspx

同步客户端套接字示例
http://msdn.microsoft.com/en-CA/library/kb5kfec7.aspx

从这些中大量借用,我想出了以下内容。(它们在 C# 中,但将它们翻译成 VB.NET 应该不是很困难。)

ACE_Server.exe 是一个控制台应用程序。它会一直监听连接,直到你用Ctrl+杀死它C

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;

public class SynchronousSocketListener
{
    // Incoming data from the client.
    public static string data = null;

    public static void StartListening()
    {
        // Data buffer for incoming data.
        byte[] bytes = new Byte[1024];

        // Establish the local endpoint for the socket.
        IPHostEntry ipHostEntry = Dns.GetHostEntry("localhost");
        IPAddress ipAddress = ipHostEntry.AddressList[0];
        IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 11000);

        // Create a TCP/IP socket.
        Socket listener = new Socket(AddressFamily.InterNetwork,
                SocketType.Stream, ProtocolType.Tcp);

        // Bind the socket to the local endpoint and 
        // listen for incoming connections.
        try
        {
            listener.Bind(localEndPoint);
            listener.Listen(10);

            // Start listening for connections.
            while (true)
            {
                Console.WriteLine("Waiting for a connection...");
                // Program is suspended while waiting for an incoming connection.
                Socket handler = listener.Accept();
                data = null;

                // An incoming connection needs to be processed.
                while (true)
                {
                    bytes = new byte[1024];
                    int bytesRec = handler.Receive(bytes);
                    data += Encoding.ASCII.GetString(bytes, 0, bytesRec);
                    if (data.IndexOf("<EOF>") > -1)
                    {
                        break;
                    }
                }

                // Show the data on the console.
                Console.WriteLine("Text received : {0}", data);

                // do the database stuff
                string sql = data.Substring(0, data.Length - 5);  // remove "<EOF>" terminator
                var con = new System.Data.OleDb.OleDbConnection(@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\__tmp\testData.accdb;");
                var cmd = new System.Data.OleDb.OleDbCommand(sql, con);
                var adapter = new System.Data.OleDb.OleDbDataAdapter();
                adapter.SelectCommand = cmd;
                var ds = new System.Data.DataSet();
                adapter.Fill(ds, "Batch data");

                var sw = new System.IO.StringWriter();
                ds.Tables["Batch data"].WriteXml(sw, System.Data.XmlWriteMode.IgnoreSchema);

                // send the data back to the client.
                byte[] msg = Encoding.ASCII.GetBytes(sw.ToString());
                int bytesSent = handler.Send(msg);
                Console.WriteLine(bytesSent.ToString() + " bytes sent.");
                handler.Shutdown(SocketShutdown.Both);
                handler.Close();
            }
        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
        }

        Console.WriteLine("\nPress ENTER to continue...");
        Console.Read();

    }

    public static int Main(String[] args)
    {
        StartListening();
        return 0;
    }
}

ACE_Client.exe 是一个 Windows 窗体应用程序。请注意,它附加"<EOF>"到 SQL 字符串,以便服务器组件知道何时停止读取:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Windows.Forms;

namespace ACE_Client
{
    public partial class Form1 : Form
    {
        public static string data = null;

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            // Data buffer for incoming data.
            byte[] bytes = new byte[1024];

            // Establish the remote endpoint for the socket.
            // This example uses port 11000 on the local computer.
            IPHostEntry ipHostEntry = Dns.GetHostEntry("localhost");
            IPAddress ipAddress = ipHostEntry.AddressList[0];
            IPEndPoint remoteEP = new IPEndPoint(ipAddress, 11000);

            // Create a TCP/IP  socket.
            Socket sock = new Socket(AddressFamily.InterNetwork,
                    SocketType.Stream, ProtocolType.Tcp);
            sock.Connect(remoteEP);

            string sql = "SELECT * FROM ExpenseDetails";
            byte[] msg = Encoding.ASCII.GetBytes(sql + "<EOF>");

            // Send the data through the socket.
            int bytesSent = sock.Send(msg);

            // Receive the response from the remote device.
            data = null;
            while (true)
            {
                bytes = new byte[1024];
                int bytesRec = sock.Receive(bytes);
                data += Encoding.ASCII.GetString(bytes, 0, bytesRec);
                if (data.IndexOf("</NewDataSet>") > -1)
                {
                    break;
                }
            }

            // Release the socket.
            sock.Shutdown(SocketShutdown.Both);
            sock.Close();

            var dsa = new DataSet();
            dsa.ReadXml(new System.Xml.XmlTextReader(new System.IO.StringReader(data)));
            dataGridView1.DataSource = dsa.Tables[0];
        }
    }
}
于 2013-05-16T18:39:45.630 回答