Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/336.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 序列化对象准备通过TCPClient流发送_C#_Serialization_Tcp_Tcpclient_Tcplistener - Fatal编程技术网

C# 序列化对象准备通过TCPClient流发送

C# 序列化对象准备通过TCPClient流发送,c#,serialization,tcp,tcpclient,tcplistener,C#,Serialization,Tcp,Tcpclient,Tcplistener,我已经使用TcpListener和TcpClient设置了服务器和客户端 我想将一个对象发送到我的服务器应用程序进行处理 我使用System.Runtime.Serialization和下面的方法发现了,但我不想东拉西扯地发现我是在用冗长的方式做这件事 问题:通过TCP流处理和发送对象的最佳方式是什么 发送和接收 下面是我的对象的一个示例: // Create a new house to send house newHouse = new house(); // Set variables

我已经使用
TcpListener
TcpClient
设置了服务器和客户端

我想将一个对象发送到我的服务器应用程序进行处理

我使用System.Runtime.Serialization和下面的方法发现了
,但我不想东拉西扯地发现我是在用冗长的方式做这件事

问题:通过TCP流处理和发送对象的最佳方式是什么

发送和接收

下面是我的对象的一个示例:

// Create a new house to send
house newHouse = new house();

// Set variables
newHouse.street = "Mill Lane";
newHouse.postcode = "LO1 BT5";
newHouse.house_number = 11;
newHouse.house_id = 1;
newHouse.house_town = "London";

您的答案暗示了以下对象(通常使用命名类):

现在,您可以序列化对象:

void Send(Stream stream)
{
    BinaryFormatter binaryFmt = new BinaryFormatter();
    House h = new House()
    {
        Street = "Mill Lane",
        PostalCode = "LO1 BT5",
        HouseNumber = 11,
        HouseID = 1,
        City = "London"
    };

    binaryFmt.Serialize(stream, h);
}

假设您有一个类
房屋
(可在连接的两侧使用),如下所示:

[Serializable]
public class House
{
    public string Street { get; set; }
    public string ZipCode { get; set; }
    public int Number { get; set; }
    public int Id { get; set; }
    public string Town { get; set; }
}
// Create a new house to send house and set values.
var newHouse = new House
    {
        Street = "Mill Lane", 
        ZipCode = "LO1 BT5", 
        Number = 11, 
        Id = 1, 
        Town = "London"
    };  

var xmlSerializer = new XmlSerializer(typeof(House));
var networkStream = tcpClient.GetStream();
if (networkStream.CanWrite)
{
    xmlSerializer.Serialize(networkStream, newHouse);
}
您可以将该类序列化为
内存流
。然后,您可以在
TcpClient
连接中这样使用:

[Serializable]
public class House
{
    public string Street { get; set; }
    public string ZipCode { get; set; }
    public int Number { get; set; }
    public int Id { get; set; }
    public string Town { get; set; }
}
// Create a new house to send house and set values.
var newHouse = new House
    {
        Street = "Mill Lane", 
        ZipCode = "LO1 BT5", 
        Number = 11, 
        Id = 1, 
        Town = "London"
    };  

var xmlSerializer = new XmlSerializer(typeof(House));
var networkStream = tcpClient.GetStream();
if (networkStream.CanWrite)
{
    xmlSerializer.Serialize(networkStream, newHouse);
}

当然,您必须进行更多的调查,以使程序毫无例外地运行。(例如,检查
memoryStream.Length
不要大于int,a.s.o.),但我希望我给了您正确的建议,以帮助您前进;-)

你可以简单地用
[Serializable]
属性装饰你的
房子
类。(您不需要定义其他答案中发布的所有其他内容)

然后,您可以通过使用
BinaryFormatter
类对该对象进行序列化,从而在线发送该对象

您是否考虑过设置WCF服务而不是使用TcpListener和TcpClient?让生活变得容易多了

例如,您可以定义一个返回房屋的服务

[ServiceContract]
public interface IService
{
    [OperationContract]
    House GetHouse(int houseId);
}

请参阅实际示例。

如何将xml房屋流反序列化回接收端的房屋对象? 我指的是Fischermaen回答中给出的解决方案

在我的接收端,我可以使用以下命令在我的输出窗口中看到字符串表示:

ASCIIEncoding encoder = new ASCIIEncoding();
            System.Diagnostics.Debug.WriteLine(encoder.GetString(message, 0, bytesRead));
先谢谢你

编辑*

好吧,这个解决方案对我很有效。可能需要整理一下

下面是一个反序列化字符串的方法:

public static T DeserializeFromXml<T>(string xml)
    {
        T result;
        XmlSerializer ser = new XmlSerializer(typeof(T));
        using (TextReader tr = new StringReader(xml))
        {
            result = (T)ser.Deserialize(tr);
        }
        return result;
    }
publicstatict反序列化fromXML(字符串xml)
{
T结果;
XmlSerializer ser=新的XmlSerializer(typeof(T));
使用(TextReader tr=new StringReader(xml))
{
结果=(T)序列反序列化(tr);
}
返回结果;
}
然后从我的TPC/IP接收端调用如下方法:

TcpClient tcpClient = (TcpClient)client;
        NetworkStream clientStream = tcpClient.GetStream();


        byte[] message = new byte[4096];
        int bytesRead;

        while (true)
        {
            bytesRead = 0;

            try
            {
                //blocks until a client sends a message
                bytesRead = clientStream.Read(message, 0, 4096);
            }
            catch
            {
                //a socket error has occured
                break;
            }

            if (bytesRead == 0)
            {
                //the client has disconnected from the server
                break;
            }


            //message has successfully been received
            ASCIIEncoding encoder = new ASCIIEncoding();
            System.Diagnostics.Debug.WriteLine(encoder.GetString(message, 0, bytesRead));

            House house = DeserializeFromXml<House>(encoder.GetString(message, 0, bytesRead));

            //Send Message Back
            byte[] buffer = encoder.GetBytes("Hello Client - " + DateTime.Now.ToLongTimeString());

            clientStream.Write(buffer, 0, buffer.Length);
            clientStream.Flush();
        }

        tcpClient.Close();
    }
TcpClient TcpClient=(TcpClient)客户端;
NetworkStream clientStream=tcpClient.GetStream();
字节[]消息=新字节[4096];
int字节读取;
while(true)
{
字节读取=0;
尝试
{
//阻塞,直到客户端发送消息
bytesRead=clientStream.Read(消息,04096);
}
抓住
{
//发生套接字错误
打破
}
如果(字节读==0)
{
//客户端已断开与服务器的连接
打破
}
//消息已成功接收
ascienceoding编码器=新的ascienceoding();
System.Diagnostics.Debug.WriteLine(encoder.GetString(message,0,bytesRead));
House=DeserializeFromXml(encoder.GetString(message,0,bytesRead));
//发回消息
byte[]buffer=encoder.GetBytes(“Hello Client-”+DateTime.Now.ToLongTimeString());
Write(buffer,0,buffer.Length);
clientStream.Flush();
}
tcpClient.Close();
}

首先创建一个空的ServerApplication和ClientApplication作为控制台应用程序,以简化示例

然后,将可序列化对象的定义放入单独的程序集中,然后向每个项目(服务器和客户端)添加对共享程序集的引用。必须共享相同的对象,而不仅仅是相同的类副本

生成DLL> 在解决方案资源管理器>添加新项目中的解决方案“服务器应用程序”中右键单击…->选择类库 (例如,将此项目命名为MySharedHouse) 将默认的Class1重命名为House并完成它

[Serializable]
public class House
{
    public string Street { get; set; }
    public string ZipCode { get; set; }
    public int Number { get; set; }
    public int Id { get; set; }
    public string Town { get; set; }
}

正确的clic在我的共享房屋和建设

现在dll已经生成,我们需要将其添加到服务器项目和客户端项目中。 在ServerApplication>addreference>Browse中单击鼠标右键clic并查找dll,如本例所示

Projects\ServerApplication\MySharedHouse\bin\Debug\MySharedHouse.dll

使用相同的dll(相同路径)在ClientApplication中重复此过程

现在,您可以将ServerApplication和ClientApplication中的House类实例作为单个对象使用,只需在顶部添加一句话“using MySharedHouse”

服务器代码

using System;
using System.Net;
using System.Net.Sockets;
using System.Runtime.Serialization.Formatters.Binary;
using System.Threading;
using MySharedHouse;

namespace ServerApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            MessageServer s = new MessageServer(515);
            s.Start();
        }
    }

    public class MessageServer
    {
        private int _port;
        private TcpListener _tcpListener;
        private bool _running;
        private TcpClient connectedTcpClient;
        private BinaryFormatter _bFormatter;
        private Thread _connectionThread;

        public MessageServer(int port)
        {
            this._port = port;
            this._tcpListener = new TcpListener(IPAddress.Loopback, port);
            this._bFormatter = new BinaryFormatter();
        }

        public void Start()
        {
            if (!_running)
            {
                this._tcpListener.Start();
                Console.WriteLine("Waiting for a connection... ");
                this._running = true;
                this._connectionThread = new Thread
                    (new ThreadStart(ListenForClientConnections));
                this._connectionThread.Start();
            }
        }

        public void Stop()
        {
            if (this._running)
            {
                this._tcpListener.Stop();
                this._running = false;
            }
        }

        private void ListenForClientConnections()
        {
            while (this._running)
            {
                this.connectedTcpClient = this._tcpListener.AcceptTcpClient();
                Console.WriteLine("Connected!");
                House house = new House();
                house.Street = "Evergreen Terrace";
                house.ZipCode = "71474";
                house.Number = 742;
                house.Id = 34527;
                house.Town = "Springfield";
                _bFormatter.Serialize(this.connectedTcpClient.GetStream(), house);
                Console.WriteLine("send House!");
            }
        }
    }
}
using System;
using System.Net.Sockets;
using System.Runtime.Serialization.Formatters.Binary;
using System.Threading;
using MySharedHouse;

namespace ClientApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            MessageClient client = new MessageClient(515);
            client.StartListening();
        }
    }

    public class MessageClient
    {
        private int _port;
        private TcpClient _tcpClient;
        private BinaryFormatter _bFormatter;
        private Thread _listenThread;
        private bool _running;
        private House house;

        public MessageClient(int port)
        {
            this._port = port;
            this._tcpClient = new TcpClient("127.0.0.1", port);
            this._bFormatter = new BinaryFormatter();
            this._running = false;
        }

        public void StartListening()
        {
            lock (this)
            {
                if (!_running)
                {
                    this._running = true;
                    this._listenThread = new Thread
                        (new ThreadStart(ListenForMessage));
                    this._listenThread.Start();
                }
                else
                {
                    this._running = true;
                    this._listenThread = new Thread
                        (new ThreadStart(ListenForMessage));
                    this._listenThread.Start();
                }
            }
        }

        private void ListenForMessage()
        {
            Console.WriteLine("Reading...");
            try
            {
                while (this._running)
                {
                    this.house = (House)this._bFormatter.Deserialize(this._tcpClient.GetStream());
                    Console.WriteLine(this.house.Street);
                    Console.WriteLine(this.house.ZipCode);
                    Console.WriteLine(this.house.Number);
                    Console.WriteLine(this.house.Id);
                    Console.WriteLine(this.house.Town);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                Console.ReadLine();
            }
        }
    }
}
客户端代码

using System;
using System.Net;
using System.Net.Sockets;
using System.Runtime.Serialization.Formatters.Binary;
using System.Threading;
using MySharedHouse;

namespace ServerApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            MessageServer s = new MessageServer(515);
            s.Start();
        }
    }

    public class MessageServer
    {
        private int _port;
        private TcpListener _tcpListener;
        private bool _running;
        private TcpClient connectedTcpClient;
        private BinaryFormatter _bFormatter;
        private Thread _connectionThread;

        public MessageServer(int port)
        {
            this._port = port;
            this._tcpListener = new TcpListener(IPAddress.Loopback, port);
            this._bFormatter = new BinaryFormatter();
        }

        public void Start()
        {
            if (!_running)
            {
                this._tcpListener.Start();
                Console.WriteLine("Waiting for a connection... ");
                this._running = true;
                this._connectionThread = new Thread
                    (new ThreadStart(ListenForClientConnections));
                this._connectionThread.Start();
            }
        }

        public void Stop()
        {
            if (this._running)
            {
                this._tcpListener.Stop();
                this._running = false;
            }
        }

        private void ListenForClientConnections()
        {
            while (this._running)
            {
                this.connectedTcpClient = this._tcpListener.AcceptTcpClient();
                Console.WriteLine("Connected!");
                House house = new House();
                house.Street = "Evergreen Terrace";
                house.ZipCode = "71474";
                house.Number = 742;
                house.Id = 34527;
                house.Town = "Springfield";
                _bFormatter.Serialize(this.connectedTcpClient.GetStream(), house);
                Console.WriteLine("send House!");
            }
        }
    }
}
using System;
using System.Net.Sockets;
using System.Runtime.Serialization.Formatters.Binary;
using System.Threading;
using MySharedHouse;

namespace ClientApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            MessageClient client = new MessageClient(515);
            client.StartListening();
        }
    }

    public class MessageClient
    {
        private int _port;
        private TcpClient _tcpClient;
        private BinaryFormatter _bFormatter;
        private Thread _listenThread;
        private bool _running;
        private House house;

        public MessageClient(int port)
        {
            this._port = port;
            this._tcpClient = new TcpClient("127.0.0.1", port);
            this._bFormatter = new BinaryFormatter();
            this._running = false;
        }

        public void StartListening()
        {
            lock (this)
            {
                if (!_running)
                {
                    this._running = true;
                    this._listenThread = new Thread
                        (new ThreadStart(ListenForMessage));
                    this._listenThread.Start();
                }
                else
                {
                    this._running = true;
                    this._listenThread = new Thread
                        (new ThreadStart(ListenForMessage));
                    this._listenThread.Start();
                }
            }
        }

        private void ListenForMessage()
        {
            Console.WriteLine("Reading...");
            try
            {
                while (this._running)
                {
                    this.house = (House)this._bFormatter.Deserialize(this._tcpClient.GetStream());
                    Console.WriteLine(this.house.Street);
                    Console.WriteLine(this.house.ZipCode);
                    Console.WriteLine(this.house.Number);
                    Console.WriteLine(this.house.Id);
                    Console.WriteLine(this.house.Town);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                Console.ReadLine();
            }
        }
    }
}

哇!第一个通过TCP/IP发送的房屋

您可以直接序列化到tcpClient的流。@L.B:谢谢您的提示,我用这种方式更改了示例!