如何使用套接字</t>发送或返回List <t>

时间:2013-03-23 15:04:33

标签: c# winforms sockets c#-4.0

是服务器和客户端套接字。我想学习一种方法如何将List<T>IEnumerable<T>对象发送到客户端到服务器或服务器到客户端。 我想将服务器端的TaskManager线程列表发送到客户端。这段代码逐行发送,我想发送complate列表。我该怎么办?

private static IEnumerable<string> TaskManager()
{
    List<string> lst = new List<string>();

    foreach (System.Diagnostics.Process p in
    Process.GetProcesses().OrderBy(o => o.ProcessName))
    {
        lst.Add(p.ProcessName + "_" + p.Id);
    }
    return lst.AsParallel();
}

....
....
....

while (true)
{
    Socket socket = Listener.AcceptSocket();
    try
    {
        //open stream
        Stream stream = new NetworkStream(socket);
        StreamReader sr = new StreamReader(stream);
        StreamWriter sw = new StreamWriter(stream);
        sw.AutoFlush = true;
        while (true)
        {
            Parallel.ForEach(
                TaskManager(), item=>
                    sw.WriteLine(item)
                );
        }

        stream.Close();
        stream.Dispose();

    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }

    Console.WriteLine("Disconnected: {0}", socket.RemoteEndPoint);
    socket.Close();
    socket.Dispose();
}

3 个答案:

答案 0 :(得分:3)

您可以使用BinaryFormatter序列化和反序列化列表。

using System.Runtime.Serialization.Formatters.Binary;

// Server side
Stream stream = new NetworkStream(socket);
var bin = new BinaryFormatter();
bin.Serialize(stream, TaskManager());

// Client side
Stream stream = new NetworkStream(socket);
var bin = new BinaryFormatter();
var list = (List<string>)bin.Deserialize(stream);

答案 1 :(得分:1)

您可以自己实现解决方案的所有方面,即序列化,压缩,发送,接收等。大多数事情都可以通过阅读WCFSystem.Net命名空间来找到。但是,我可以在这里使用network library NetworkComms.Net为您提供一个非常简洁的解决方案。

对于客户:

using System;
using NetworkCommsDotNet;

namespace Client
{
    class Program
    {
        static void Main(string[] args)
        {
            //Create a connection
            Connection connection = TCPConnection.GetConnection(new ConnectionInfo("127.0.0.1", 10000));

            //Make a request for the threadIds and get the answer in one statement. 
            string[] taskManagerThreadIds = connection.SendReceiveObject<string[]>("ThreadIdRequest", "ThreadIds", 2000);

            Console.WriteLine("Server provided an array containing {0} ids", taskManagerThreadIds.Length);

            Console.WriteLine("Send completed. Press any key to exit client.");
            Console.ReadKey(true);
            NetworkComms.Shutdown();
        }
    }
}

对于服务器:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Diagnostics;

using NetworkCommsDotNet;

namespace Server
{
    class Program
    {
        static void Main(string[] args)
        {
            NetworkComms.AppendGlobalIncomingPacketHandler<object>("ThreadIdRequest", (packetHeader, connection, incomingPlayer) =>
            {
                //Reply with the requested threadIds
                Console.WriteLine("Received thread ID request from {0}.", connection.ToString());
                connection.SendObject("ThreadIds", TaskManager().ToArray());
            });

            //Start listening for incoming TCP Connections
            TCPConnection.StartListening(true);

            Console.WriteLine("Server ready. Press any key to shutdown server.");
            Console.ReadKey(true);
            NetworkComms.Shutdown();
        }

        private static IEnumerable<string> TaskManager()
        {
            List<string> lst = new List<string>();

            foreach (System.Diagnostics.Process p in
            Process.GetProcesses().OrderBy(o => o.ProcessName))
            {
                lst.Add(p.ProcessName + "_" + p.Id);
            }
            return lst.AsParallel();
        }
    }
}

您显然需要从website下载NetworkComms.Net DLL,以便您可以在“使用NetworkCommsDotNet”参考中添加它。另请参阅客户端示例中的服务器IP地址当前为“127.0.0.1”,如果您在同一台计算机上同时运行服务器和客户端,这应该可以使用。

免责声明:我是该图书馆的开发人员之一。

答案 2 :(得分:0)

如果您需要可靠且强大的解决方案,请使用WCF而不是自己实现序列化。

此外,从并行线程写入流将无法正常工作。来自不同线程的部分线将混合成一些无形的垃圾:

Parallel.ForEach(
   TaskManager(), item=>
   sw.WriteLine(item)
);