2011-04-03 72 views
0

我正在使用C型TCP套接字send()recv()。我有一个连接在用户A和用户B之间运行,用户A充当服务器,用户B充当客户机。如何在会话期间获得新的套接字连接?

我想要一个被动用户C,它不会传递任何东西,但会接收来自用户A的数据。但是,新的被动用户C可以随时加入会话。 A可能会发送C不同的数据包,比发送B的数据包数量多得多。我想最好是AC在不同于AB的端口上进行通信。如何在一个不同的端口上进行此连接(不使用线程或类似方法)任意的沟通点?

编辑仍未解决。

+0

是C++对你而言好吗? – sehe 2011-04-03 22:00:33

+0

是的,C++没问题。但是我现在正在使用c-unix风格的套接字。无论哪种方式,真的 – cellpho 2011-04-03 22:22:49

回答

1

您可以设置侦听器来检测新连接,并将流量镜像到所有打开的套接字。我最近在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

概念是正确的。用户C连接到服务器A.当服务器A检测到用户C已连接时,它将B发送给它的也发送给C。这基本上是如何聊天服务器工作 – Matt 2011-04-03 22:01:23

+0

感谢您的答案。我对部分内容发生了些什么不清楚。如果服务器向C发送不同的消息,这将如何工作? – cellpho 2011-04-03 22:26:45

0

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

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