Как получить новое сокетное соединение в середине сеанса? - PullRequest
0 голосов
/ 04 апреля 2011

Я использую TCP-сокеты в стиле C с send() и recv().У меня установлено соединение между пользователем A и пользователем B, где пользователь A действует как сервер, а пользователь B действует как клиент.

Я хочу иметь пассивного пользователя C, который ничего не сообщает, но получает данные от пользователя A. Однако новый пассивный пользователь C может присоединиться к сеансу в любое время.A может отправлять C пакеты, отличные от того, что он будет отправлять B .. Я полагаю, было бы лучше, если бы AC взаимодействовал через порт, отличный от AB

. Как можно установить это соединение (без многопоточности и т.в произвольной точке связи?

edit все еще не решено.

Ответы [ 2 ]

1 голос
/ 04 апреля 2011

Вы можете настроить прослушиватель, который обнаруживает новые подключения, и зеркалировать трафик на все открытые сокеты. Я недавно написал, что я имею в виду в C #: (я посмотрю, смогу ли я быстро превратить это в образец C)

В этом примере в начале принимается только фиксированный номер входящих соединений, но изменить это очень просто.

using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Linq;

public class Demo
{
    static IList<Socket> StartServer(int numberOfClients)
    {
        using(Socket main = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
        {
            main.Bind(new IPEndPoint(IPAddress.Any, 9050));
            main.Listen(numberOfClients);

            var clients = Enumerable
                .Range(1,numberOfClients)
                .Select(i => {
                        Console.WriteLine("Waiting for 1 more client...");
                        Socket client = main.Accept();
                        Console.WriteLine("Connected to {0}", client.RemoteEndPoint);    
                        return client; })
                .ToList();
            main.Close();

            return clients;
        }
    }

    public static void Main()
    {
        var clients = StartServer(4);

        while(clients.Count()>1) // still a conversation
        {
            var copyList = clients.ToList();
            Console.WriteLine("Monitoring {0} sockets...", copyList.Count);
            Socket.Select(copyList, null, null, 10000000);

            foreach(Socket client in copyList)
            {
                byte[] data = new byte[1024];
                int recv = client.Receive(data);

                if (recv == 0)
                {
                    Console.WriteLine("Client {0} disconnected.", client.RemoteEndPoint);
                    client.Close();
                    clients.Remove(client);
                }
                else
                    foreach (var other in clients.Except(new [] {client}))
                        other.Send(data, recv, SocketFlags.None);
            }
        }
        Console.WriteLine("Last client disconnected, bye");
    }
}
0 голосов
/ 04 апреля 2011

Вы можете просто открыть 2 сокета на сервере A и связать их на 2 разных портах.Затем используйте функцию выбора для двух созданных файловых дескрипторов сокетов.

Выбор вернется в первый раз, когда один из двух клиентов установит соединение.Помните, что на стороне сервера, после принятия соединения, вы должны установить возвращаемый дескриптор нового файла (с помощью FD_SET), чтобы select мог прослушивать события, которые будут происходить в новом сокете (который возвращен из accept).

...