3

サーバーソケットとクライアントソケットがあります。List<T>IEnumerable<T>オブジェクトをクライアントからサーバーへ、またはサーバーからクライアントへ送信する方法を学びたいです。サーバー側の TaskManager スレッド リストをクライアント側に送信したい。このコードは行ごとに送信します。コンプレートリストを送信したいです。どうすればいいですか?

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

3 に答える 3

4

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);
于 2013-03-23T16:16:35.503 に答える
1

シリアル化、圧縮、送信、受信など、ソリューションのすべての側面を自分で実装できます。ほとんどのことは、WCFまたはSystem.Net名前空間について読むことで見つけることができます。ただし、ここでネットワーク ライブラリ 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();
        }
    }
}

「NetworkCommsDotNet を使用する」リファレンスに追加できるように、 Web サイトから NetworkComms.Net DLL をダウンロードする必要があることは明らかです。また、クライアントの例のサーバー IP アドレスが現在「127.0.0.1」であることも確認してください。これは、サーバーとクライアントの両方を同じマシンで実行する場合に機能するはずです。

免責事項: 私はこのライブラリの開発者の 1 人です。

于 2013-03-23T15:20:25.770 に答える
0

信頼性が高く堅牢なソリューションが必要な場合は、シリアル化を自分で実装する代わりに、WCF を使用してください。

また、並列スレッドからストリームへの書き込みが正しく機能しませんでした。異なるスレッドからの行の一部が混ざり合って、無形のゴミになります。

Parallel.ForEach(
   TaskManager(), item=>
   sw.WriteLine(item)
);
于 2013-03-23T15:09:51.243 に答える