none
Передача сокета RRS feed

  • Вопрос

  • C#; NFW 4-4,5

    Всем здравствуйте!

    Ребята помогите разобраться с вопросом передачи сокета между приложениями. Информации в просторах нашел не много, и все примеры не применимы на практике.

    В общем, обрисую задачу. Мне нужен сервер доступа. Функционал у него не особо мудреный, слушает сокет, принимает подключения, имеет механизмы идентификации клиента и анти ддоса. Помимо всего прочего этот сервер ничего не должен делать, идентифицировать клиента и передать его серверу который ему нужен. Это все что от него требуется. Когда то давным давно, натыкался на метод "Socket.DuplicateAndClose", это то что мне нужно, подумал я. Но вот беда, не могу найти ни одного рабочего примера как передать сокет между приложениями. В другой апп домен - сколько угодно. В пределах одного приложения - пожалуйста. Но это все не то. Программы физически разные, 2 абсолютно разных, связанных только лишь разработчиком экзешника. Вот от сюда и вопрос, как передать SocketInformation из одного процесса в другой. Если не сложно, набросайте примерчик, ну или распишите саму логику.

Ответы

  • SocketInformation имеет атрибут Serializable, следовательно его можно через любой поток отправлять и получать. Передавайте или через файл, или через сокеты. В конце концов воспользуйтесь штатным средством межпроцессного взаимодействия .NET Remoting.

    Если сообщение помогло Вам, пожалуйста, не забудьте отметить его как ответ данной темы. Удачи в программировании!

    • Помечено в качестве ответа JusteG 8 июня 2014 г. 11:40
  • Спасибо за помощь, все получилось.

    На будущее, оставлю здесь код, мало ли, пригодится кому ни будь.

    Итак для теста на потребуется 3 программы.

    1. Сервер авторизации - "Proxy".

    2. Собственно сервер - "Server".

    3. Клиент - "Client".

    Что происходит? Первым запускаем прокси. Он принимает подключения от сервера и клиента. Затем, закрывает соединение с клиентом для себя, собирает информацию о сокете для сервера, сериализует ее и отправляет на сервер. Сервер, разворачивает у себя сериализованный сокет, и обменивается с клиентом тестовыми сообщениями.

    Зачем? Сервер авторизации. Один сокет "на улице", десятки серверов внутри, в безопасности.

    Итак, обещанный код:

    namespace Proxy
    {
        class Program
        {
            static void Main(string[] args)
            {
                Socket Sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                Sock.Bind(new IPEndPoint(IPAddress.Any, 5665));
                Sock.Listen(1);
                Socket Server = Sock.Accept();
                Console.WriteLine("Server connected!");
    
                Process ServerProc = Process.GetProcessesByName("Server")[0];
    
                Socket Sock2 = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                Sock2.Bind(new IPEndPoint(IPAddress.Any, 5660));
                Sock2.Listen(1);
                Socket Client = Sock.Accept();
                Console.WriteLine("Client connected!");
    
                SocketInformation SockToTransfer = Client.DuplicateAndClose(ServerProc.Id);
    
                XmlSerializer xmlSerializer = new XmlSerializer(typeof(SocketInformation));
                MemoryStream memStream = new MemoryStream();
                StreamWriter stWriter = new StreamWriter(memStream);
                XmlSerializerNamespaces xs = new XmlSerializerNamespaces();
                xs.Add("", "");
                xmlSerializer.Serialize(stWriter, SockToTransfer, xs);
    
                Server.Send(memStream.GetBuffer());
    
                Console.ReadKey();
            }
        }
    }
    namespace Server
    {
        class Program
        {
            static void Main(string[] args)
            {
                Socket Sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                Sock.Connect("localhost", 5665);
    
                byte[] buffer = new byte[1024];
                int BytesResived = Sock.Receive(buffer);
                XmlSerializer xmlSerializer = new XmlSerializer(typeof(SocketInformation));
                MemoryStream memStream = new MemoryStream(buffer, 0, BytesResived);
                object objectFromXml = xmlSerializer.Deserialize(memStream);
    
                Socket Client = new Socket((SocketInformation)objectFromXml);
                Client.Send(Encoding.UTF8.GetBytes("Hello, client!"));
                Console.WriteLine("Message sended!");
                buffer = new byte[1024];
                BytesResived = Client.Receive(buffer);
                Console.WriteLine(Encoding.UTF8.GetString(buffer, 0, BytesResived));
    
                Console.ReadKey();
            }
        }
    }
    namespace Client
    {
        class Program
        {
            static void Main(string[] args)
            {
                Socket Sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                Sock.Connect("localhost", 5665);
                byte[] buffer = new byte[1024];
                int BytesResived = Sock.Receive(buffer);
                Console.WriteLine(Encoding.UTF8.GetString(buffer, 0, BytesResived));
                Sock.Send(Encoding.UTF8.GetBytes("Hello, server!"));
    
                Console.ReadKey();
            }
        }
    }
    • Помечено в качестве ответа JusteG 8 июня 2014 г. 11:51
    8 июня 2014 г. 11:49

Все ответы

  • SocketInformation имеет атрибут Serializable, следовательно его можно через любой поток отправлять и получать. Передавайте или через файл, или через сокеты. В конце концов воспользуйтесь штатным средством межпроцессного взаимодействия .NET Remoting.

    Если сообщение помогло Вам, пожалуйста, не забудьте отметить его как ответ данной темы. Удачи в программировании!

    • Помечено в качестве ответа JusteG 8 июня 2014 г. 11:40
  • Спасибо за помощь, все получилось.

    На будущее, оставлю здесь код, мало ли, пригодится кому ни будь.

    Итак для теста на потребуется 3 программы.

    1. Сервер авторизации - "Proxy".

    2. Собственно сервер - "Server".

    3. Клиент - "Client".

    Что происходит? Первым запускаем прокси. Он принимает подключения от сервера и клиента. Затем, закрывает соединение с клиентом для себя, собирает информацию о сокете для сервера, сериализует ее и отправляет на сервер. Сервер, разворачивает у себя сериализованный сокет, и обменивается с клиентом тестовыми сообщениями.

    Зачем? Сервер авторизации. Один сокет "на улице", десятки серверов внутри, в безопасности.

    Итак, обещанный код:

    namespace Proxy
    {
        class Program
        {
            static void Main(string[] args)
            {
                Socket Sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                Sock.Bind(new IPEndPoint(IPAddress.Any, 5665));
                Sock.Listen(1);
                Socket Server = Sock.Accept();
                Console.WriteLine("Server connected!");
    
                Process ServerProc = Process.GetProcessesByName("Server")[0];
    
                Socket Sock2 = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                Sock2.Bind(new IPEndPoint(IPAddress.Any, 5660));
                Sock2.Listen(1);
                Socket Client = Sock.Accept();
                Console.WriteLine("Client connected!");
    
                SocketInformation SockToTransfer = Client.DuplicateAndClose(ServerProc.Id);
    
                XmlSerializer xmlSerializer = new XmlSerializer(typeof(SocketInformation));
                MemoryStream memStream = new MemoryStream();
                StreamWriter stWriter = new StreamWriter(memStream);
                XmlSerializerNamespaces xs = new XmlSerializerNamespaces();
                xs.Add("", "");
                xmlSerializer.Serialize(stWriter, SockToTransfer, xs);
    
                Server.Send(memStream.GetBuffer());
    
                Console.ReadKey();
            }
        }
    }
    namespace Server
    {
        class Program
        {
            static void Main(string[] args)
            {
                Socket Sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                Sock.Connect("localhost", 5665);
    
                byte[] buffer = new byte[1024];
                int BytesResived = Sock.Receive(buffer);
                XmlSerializer xmlSerializer = new XmlSerializer(typeof(SocketInformation));
                MemoryStream memStream = new MemoryStream(buffer, 0, BytesResived);
                object objectFromXml = xmlSerializer.Deserialize(memStream);
    
                Socket Client = new Socket((SocketInformation)objectFromXml);
                Client.Send(Encoding.UTF8.GetBytes("Hello, client!"));
                Console.WriteLine("Message sended!");
                buffer = new byte[1024];
                BytesResived = Client.Receive(buffer);
                Console.WriteLine(Encoding.UTF8.GetString(buffer, 0, BytesResived));
    
                Console.ReadKey();
            }
        }
    }
    namespace Client
    {
        class Program
        {
            static void Main(string[] args)
            {
                Socket Sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                Sock.Connect("localhost", 5665);
                byte[] buffer = new byte[1024];
                int BytesResived = Sock.Receive(buffer);
                Console.WriteLine(Encoding.UTF8.GetString(buffer, 0, BytesResived));
                Sock.Send(Encoding.UTF8.GetBytes("Hello, server!"));
    
                Console.ReadKey();
            }
        }
    }
    • Помечено в качестве ответа JusteG 8 июня 2014 г. 11:51
    8 июня 2014 г. 11:49