如何在会话期间获得新的套接字连接?

时间:2011-04-03 21:47:48

标签: c sockets unix networking

我正在使用带有send()recv()的C风格TCP套接字。我在用户A和用户B之间运行连接,其中用户A充当服务器,用户B充当客户端。

我希望有一个被动用户C,它不会进行任何通信,但会从用户A接收数据。但是,新的被动用户C可以随时加入会话。 A可能会发送与发送B不同的C数据包。我想A-C最好在不同于A-B的端口上进行通信

如何在任意通信点进行此连接(没有线程等)?

编辑仍未解决。

2 个答案:

答案 0 :(得分:1)

您可以设置一个侦听器来检测新连接,并将流量镜像到所有打开的套接字。我最近写了我在C#中的意思:(我会看看我能否迅速将其变成C样本)

此示例仅在开始时接受固定的nr个传入连接,但很容易更改它。

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");
    }
}

答案 1 :(得分:0)

您只需在服务器A上打开2个套接字,然后将它们绑定在2个不同的端口上即可。 然后在2个创建的套接字文件描述符上使用select函数。

当两个客户端中的一个进行连接时,Select将首次返回。请记住,在服务器端,在接受连接之后,您应该设置返回的新文件描述符(使用FD_SET),以便选择侦听将在新套接字(从accept返回)上发生的事件。