在应用程序之间发送信息

问题描述 投票:-1回答:1

早安,

我有一个客户端应用程序,该应用程序将客户端打开的应用程序列表发送到服务器。它特别发送文件路径,文件名和主机名。我的问题是,当服务器中接收到发送的数据时,应该对发送的数据进行序列化和反序列化。我是C#的新手,所以我对序列化几乎一无所知。

这是客户端

private List<int> listedProcesses = new List<int>();
        private void SendData()
        {
            String processID = "";
            String processName = "";
            String processPath = "";
            String processFileName = "";
            String processMachinename = "";

            listBox1.BeginUpdate();
            try
            {   
                piis = GetAllProcessInfos();
                for (int i = 0; i < piis.Count; i++)
                {
                    try
                    {
                        if (!listedProcesses.Contains(piis[i].Id)) //placed this on a list to avoid redundancy
                        {
                            listedProcesses.Add(piis[i].Id);
                            processID = piis[i].Id.ToString();
                            processName = piis[i].Name.ToString();
                            processPath = piis[i].Path.ToString();
                            processFileName = piis[i].FileName.ToString();
                            processMachinename = piis[i].Machinename.ToString();
                            output.Text += "\n\nSENT DATA : \n\t" + processFileName + "\n\t" + processMachinename + "\n\t" + processID + "\n\t" + processName + "\n\t" + processPath + "\n";
                        }

                    }
                    catch (Exception ex)
                    {
                        wait.Abort();
                        output.Text += "Error..... " + ex.StackTrace;

                    }

                    NetworkStream ns = tcpclnt.GetStream();
                    String data = "";
                    data = "--++" + "  " + processFileName + " " + processMachinename + " " + processID + " " + processPath;
                    if (ns.CanWrite)
                    {
                        byte[] bf = new ASCIIEncoding().GetBytes(data);
                        ns.Write(bf, 0, bf.Length);
                        ns.Flush();
                    }
                }
            }
            finally
            {
                listBox1.EndUpdate();
            } 
        }

        private void cmd_dis_Click(object sender, EventArgs e)
        {
            if (wait != null)
            {
                wait.Abort();
                //read.Close(2000);
            }

            IPAddress ipclient = Dns.GetHostByName(Dns.GetHostName()).AddressList[0];
            String ipclnt = "+@@+" + ipclient.ToString();
            NetworkStream ns = tcpclnt.GetStream();
            if (ns.CanWrite)
            {
                byte[] bf = new ASCIIEncoding().GetBytes(ipclnt);
                ns.Write(bf, 0, bf.Length);
                ns.Flush();
            }

            tcpclnt.Close();
           // read.Close();
            Application.Exit();
        }

        private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            ProcessInfoItem pii = piis.FirstOrDefault(x => x.Id == (int)(sender as ListBox).SelectedValue);
            if (pii != null)
            {
                string hostName = System.Net.Dns.GetHostName();

                textBox4.Text = listBox1.SelectedValue.ToString();
                textBox5.Text = (pii.FileName);
                textBox6.Text = (pii.Path);
                textBox7.Text = (pii.Machinename);
            }
        }

        private List<ProcessInfoItem> piis = new List<ProcessInfoItem>();
        private void Form1_Load(object sender, EventArgs e)
        {
            piis = GetAllProcessInfos();
            listBox1.DisplayMember = "Name";
            listBox1.ValueMember = "Id";
            listBox1.DataSource = piis;

        }
        private List<ProcessInfoItem> GetAllProcessInfos()
        {

            List<ProcessInfoItem> result = new List<ProcessInfoItem>();
            Process currentProcess = Process.GetCurrentProcess();
            Process[] processes = Process.GetProcesses();
            foreach (Process p in processes)
            {
                if (!String.IsNullOrEmpty(p.MainWindowTitle))
                {
                    //ProcessInfoItem pii = new ProcessInfoItem(p.Id, p.MainModule.ModuleName, p.MainModule.FileName, p.MainWindowTitle);
                    ProcessInfoItem pii = new ProcessInfoItem(p.Id, p.MainModule.ModuleName, p.MainWindowTitle, p.MainModule.FileName, Environment.MachineName);
                    result.Add(pii);
                }
            }
            return result;
        }
        public class ProcessInfoItem
        {
            public int Id { get; set; }
            public string Name { get; set; }
            public string FileName { get; set; }
            public string Path { get; set; }
            public string Machinename { get; set; }
            public ProcessInfoItem(int id, string name, string filename, string path, string machinename)
            {
                this.Id = id;
                this.Name = name;
                this.FileName = filename;
                this.Path = path;
                this.Machinename = machinename;
            }
        }

这是需要反序列化的服务器

  private void recieveData()
        {
            NetworkStream nStream = tcpClient.GetStream();
            ASCIIEncoding ascii = null;
            while (!stopRecieving)
            {
                if (nStream.CanRead)
                {
                    byte[] buffer = new byte[1024];
                    nStream.Read(buffer, 0, buffer.Length);
                    ascii = new ASCIIEncoding();
                    recvDt = ascii.GetString(buffer);
                    /*Received message checks if it has +@@+ then the ip is disconnected*/
                    bool f = false;
                    f = recvDt.Contains("+@@+");
                    if (f)
                    {
                        string d = "+@@+";
                        recvDt = recvDt.TrimStart(d.ToCharArray());
                        clientDis();
                        stopRecieving = true;
                    }

                    //else if (recvDt.Contains("^^"))
                    //{
                    //    new Transmit_File().transfer_file(file, ipselected);
                    //}
                    /* ++-- shutsdown/restrt/logoff/abort*/
                    else if (recvDt.Contains("++--"))
                    {
                        string d = "++--";
                        recvDt = recvDt.TrimStart(d.ToCharArray());
                        this.Invoke(new rcvData(addToOutput));
                        clientDis();
                    } 
                    /*--++ Normal msg*/
                    else if (recvDt.Contains("--++"))
                    {

                        string d = "--++";
                        recvDt = recvDt.TrimStart(d.ToCharArray());
                        this.Invoke(new rcvData(addToOutput));

                    }
                }
                Thread.Sleep(1000);
            }

        }


public void addToOutput()
        {
            if (recvDt != null && recvDt != "")
            {
                output.Text += "\n Received Data : " + recvDt;
                recvDt = null;



            }

        }

谢谢。

c# .net winforms serialization client-server
1个回答
2
投票

您基本上需要Interprocess Communication

作为一种选择,您可以使用WCF在客户端和服务器应用程序之间进行通信。

您可以创建服务并将其托管在将从其他应用程序接收数据并在其他应用程序中使用服务以发送数据和显示响应的应用程序中。

这里是一个简单的例子。在此示例中,我创建了2个应用程序。 Application2每10秒自动将数据发送到Application1一次,Application1将响应发送回给Application2,Application2将显示响应。

要运行示例代码,请按照以下步骤操作:

  1. 使用2个控制台应用程序Application1和Application2创建解决方案
  2. 向两个项目添加System.ServiceModel引用。
  3. 在每个项目的program.cs中粘贴以下代码。
  4. 右键单击解决方案,然后在属性中,使解决方案成为多个启动项目,并将每个项目的操作设置为“开始”
  5. 按Ctrl + F5运行项目
  6. 在Application1窗口中,您将看到服务正在运行的消息。
  7. [Application2将每隔10秒发送DateTime.Now到Application 2,并将收到来自Application 2的响应并将其显示在Application1窗口中。

Application1 Program.cs

using System;
using System.ServiceModel;

namespace Application1
{
    [ServiceContract]
    public interface IEchoService
    {
        [OperationContract]
        string Echo(string value);
    }

    public class EchoService : IEchoService
    {
        public string Echo(string value)
        {
            return string.Format("You send me data'{0}'", value);
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            using (ServiceHost host = new ServiceHost(typeof(EchoService), new Uri[] { new Uri("http://localhost:8000") }))
            {
                host.AddServiceEndpoint(typeof(IEchoService), new BasicHttpBinding(), "Echo");
                host.Open();
                Console.WriteLine("Service is running...");
                Console.WriteLine("Press Enter to exit if you want to close service.");
                Console.ReadLine();
                host.Close();
            }
        }
    }
}

Application2 Program.cs

using System;
using System.ServiceModel;
using System.ServiceModel.Channels;

namespace Application2
{
    [ServiceContract]
    public interface IEchoService
    {
        [OperationContract]
        string Echo(string value);
    }

    class Program
    {
        static void Main(string[] args)
        {
            //In real implementation, use server IP instead of localhost
            ChannelFactory<IEchoService> factory = new ChannelFactory<IEchoService>(new BasicHttpBinding(), new EndpointAddress("http://localhost:8000/Echo"));
            IEchoService proxy = factory.CreateChannel();
            int processedSeccond = 0;
            while (true)
            {
                var dateTime = DateTime.Now;
                if (dateTime.Second % 10 == 0 && dateTime.Second!=processedSeccond)
                {
                    processedSeccond = dateTime.Second;
                    string data= dateTime.ToString(); //or Console readLine for manual data entry
                    Console.WriteLine("Recieved Response: " + proxy.Echo(str));
                }
            }
        }
    }
}

结果

enter image description here

就这么简单。您可以根据需要更改代码。

将复杂数据传递给服务的示例:

[DataContract]
public class MyMessageClass
{
    [DataMember]
    public string MyValue1 {get;set;}

    [DataMember]
    public string MyValue2 {get;set;}
}

然后,您可以更新接口和服务的补充,只需使用它,而无需序列化和反序列化任何东西,所有事情都将由WCF在后台完成。

请注意,您可以将WCF服务与Windows窗体应用程序和控制台应用程序一起使用,并且可以继续以自己的方式开发项目。您唯一需要做的更改是向将在服务器上运行的应用程序中添加服务,然后在将在客户端上运行的应用程序中使用该服务。它与您的应用程序的逻辑无关。为了简单起见,我提供的示例位于控制台应用程序中。

© www.soinside.com 2019 - 2024. All rights reserved.