使用C#中的socket发送复杂对象,但也是简单的文本字符串

时间:2011-04-22 21:38:36

标签: c# sockets serialization deserialization

我的目标是使用socket将简单的文本数据和复杂的数据发送到客户端应用程序。这是我的一些代码

 private void button1_Click(object sender, EventArgs e)
 {

        byte[] data;
        data = Encoding.ASCII.GetBytes("Welcome!!!");
        ns.Write(data, 0, data.Length);
        ns.Flush();

        List<Person> list = new List<Person>();
        for (int a = 0; a < 5; a++)
        {
            Person person = new Person();
            person.Name = textBox1.Text;
            person.Age = int.Parse(textBox2.Text);
            list.Add(person);
        }

        BinaryFormatter formatter = new BinaryFormatter();
        for (int a = 0; a < 5; a++)
        {
            formatter.Serialize(ns, list[a]);
        }
        ns.Flush();
 }

在客户端我编写此代码以将所有数据添加到listview

 private void AddToListView()
 {
         while (true && ns.DataAvailable)
         {
            byte[] data = new byte[1024];
            int recv;
            recv = ns.Read(data, 0, data.Length);
            textFromServer = Encoding.ASCII.GetString(data, 0, recv);
            ns.Flush();
            listView1.Items.Add(textFromServer);

            temp = formatter.Deserialize(ns) as Person;
            ns.Flush();
            listView1.Items.Add(temp.Name);
            listView1.Items.Add(temp.Age);
        }
    }

但是当我调试应用程序时,没有任何反应...如果我删除了网络流read()过程,应用程序运行良好..问题是,我不仅需要发送用户对象,而且还简单的文字给客户..有人可以帮我吗?

是否有可能同时使用networkstream.read()和binaryformatter.deserialize()?或者,我们必须选择其中一个?

我的意思是当发送/接收简单文本时,我们使用networkstream.read()/ write(),,对于复杂对象,我们使用serialize / deserialize ..它可能吗?

2 个答案:

答案 0 :(得分:4)

您正在做的问题是服务器和客户端需要具有商定的协议来发送和接收数据。例如,您的客户端代码将读取您进行的第一次ns.Read调用中可用的所有内容。没有任何信号表示一种数据类型的结束和下一种数据的开始,因此您没有商定的方法来发送/读取数据。

最简单的方法可能是将数据封装到另一个可以包含字符串和对象的对象中。

[Serializable]
public class EncapsulatedData{
    public EncapsulatedData(){}
    public string Message{ get; set; }
    public ISerializable Object{ get; set; }
}

并且您将Object设置为您的ISerializable类型,例如Person。然后,您应该能够在客户端上反序列化并检查消息或对象。

有更简洁的方法可以做到这一点,但上述技巧应该适合你。

答案 1 :(得分:1)

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

namespace ClientServer
{
    class ClientServerProgram
    {    
       public static void SendHeader(string sMIMEHeader, int iTotBytes, string sStatusCode, ref Socket mySocket)
      {
        String sBuffer = "";
        // if Mime type is not provided set default to text/html
        if (sMIMEHeader.Length == 0)
        {
            sMIMEHeader = "text/html";  // Default Mime Type is text/html
        }
        sBuffer = sBuffer + "HTTP/1.1" + sStatusCode + "\r\n";
        sBuffer = sBuffer + "Server: cx1193719-b\r\n";
        sBuffer = sBuffer + "Content-Type: " + sMIMEHeader + "\r\n";
        sBuffer = sBuffer + "Accept-Ranges: bytes\r\n";
        sBuffer = sBuffer + "Content-Length: " + iTotBytes + "\r\n\r\n";
        Byte[] bSendData = Encoding.ASCII.GetBytes(sBuffer);
        mySocket.Send(Encoding.ASCII.GetBytes(sBuffer),Encoding.ASCII.GetBytes(sBuffer).Length, 0);
        Console.WriteLine("Total Bytes : " + iTotBytes.ToString());
      }

        public static void ReceiveCallback(IAsyncResult AsyncCall)
        {            
            System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
            string messageString = "I am a little busy, come back later!";
            Byte[] message = encoding.GetBytes(messageString);

            Socket listener = (Socket)AsyncCall.AsyncState;
            Socket client = listener.EndAccept(AsyncCall);
            Console.WriteLine("Received Connection from {0}", client.RemoteEndPoint);
            SendHeader("text/html", message.Length, "202 OK", ref client);
            client.Send(message);
            Console.WriteLine("Ending the connection");
            client.Close();
            listener.BeginAccept(new AsyncCallback(ReceiveCallback), listener);
        }

    public static void Main()
    {
       IPAddress localAddress = IPAddress.Parse("192.0.127.1");
       Socket listenSocket = new Socket(AddressFamily.InterNetwork,  SocketType.Stream, ProtocolType.Tcp);
       IPEndPoint ipEndpoint = new IPEndPoint(localAddress, 8080);
       listenSocket.Bind(ipEndpoint);
       listenSocket.Listen(1);
       listenSocket.BeginAccept(new AsyncCallback(ReceiveCallback), listenSocket);
       while (true)
       {                    
          Console.WriteLine("Waiting....");
          Thread.Sleep(1000);
       }                
    }
}