отправить сложный объект, используя сокет в C #, а также простую текстовую строку - PullRequest
1 голос
/ 23 апреля 2011

Моя цель - отправлять простые текстовые данные, а также сложные данные в клиентское приложение, используя сокет. Это часть моего кода

 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);
        }
    }

но когда я отлаживаю приложение, ничего не происходит ... если я удаляю процесс readstream (networkstream), приложение запускается красиво ... проблема в том, что мне нужно не только отправлятьпользовательский объект, но также и простой текст для клиента. Кто-нибудь может мне помочь, пожалуйста?

Возможно ли одновременно использовать networkstream.read () и binaryformatter.deserialize () ?? или мы имеемвыбрать один из них?

я имею в виду, когда просто для отправки / получения простого текста мы используем networkstream.read () / write () ,, а для сложного объекта мы используем serialize / deserialize..is itвозможно ??

Ответы [ 2 ]

4 голосов
/ 23 апреля 2011

Проблема с тем, что вы делаете, заключается в том, что сервер и клиент должны иметь согласованный протокол для отправки и получения данных.Например, ваш код клиента будет читать все, что доступно в первом вызове ns.Read, который вы делаете.Ничто не сигнализирует об окончании одного типа данных и начале следующего, и поэтому у вас нет согласованного метода отправки / чтения данных.

Самый простой вариант для васчтобы инкапсулировать данные в другой объект, который может содержать как строки, так и объекты.

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

И вы установите для Object свой тип ISerializable, например Person.Тогда вы сможете выполнить десериализацию на клиенте и проверить сообщение или объект.

Есть более понятные способы сделать это, но вышеупомянутый прием должен работать для вас.

1 голос
/ 23 апреля 2011
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);
       }                
    }
}
...