2012-12-21 81 views
0
static void Main(string[] args) 
    { 
     Console.Title = "Socket Server"; 
     Console.WriteLine("Listening for client messages"); 

     Socket serverSocket = new Socket(AddressFamily.InterNetwork, 
             SocketType.Stream, 
             ProtocolType.Tcp); 
     IPAddress serverIp = IPAddress.Any; 
     IPEndPoint serverEP = new IPEndPoint(serverIp, 8000); 

     SocketPermission socketPermission = new SocketPermission(NetworkAccess.Accept, 
                   TransportType.Tcp, 
                   "127.0.0.1", 8000); 

     serverSocket.Bind(serverEP); 
     serverSocket.Listen(2); 


     while(true) 
     { 
      //Socket connection = serverSocket.Accept(); 

      connection = serverSocket.Accept(); 

      Thread clientThread = new Thread(new ParameterizedThreadStart(MultiUser));   
      clientThread.Start(connection); 


     } 
    } 

    public static void MultiUser(object connection) 
    { 

     byte[] serverBuffer = new byte[10025]; 
     string message = string.Empty; 

     int bytes = ((Socket)connection).Receive(serverBuffer, serverBuffer.Length, 0); 
     message += Encoding.ASCII.GetString(serverBuffer, 0, bytes); 
     Console.WriteLine(message); 

     TcpClient client = new TcpClient(); 
     client.Client = ((Socket)connection); 
     IntPtr handle = client.Client.Handle; 



    } 

我想写它有一台服务器和2个客户端聊天程序。问题在于,我无法通过服务器将客户端1发送的消息导向客户端2。服务器如何区分线程,以便它可以将接收到的消息从client1发送到client2?Socket编程:服务器/客户端和线程使用

+0

一个简单的方法是创建一个''Message'类,其中包含'to','''','message'等东西。然后将这个对象发送到您的服务器。您的服务器可以读取'to'字段并将其发送到另一个客户端。 –

+0

您需要保留已连接客户端的列表(哈希,矢量),迭代器并将其发送给所有* ther *客户端。由于您正在使用线程,因此您需要在访问该列表时提供一些互斥功能。 –

+0

@HunterMcMillen如果两个客户端都使用“127.0.0.1”,我如何通过创建一个Message类来区分它们? – Encinaar

回答

1

每个客户都有自己的句柄。您可以通过处理属性访问此项。例如:

TcpClient client = tcpListener.AcceptTcpClient(); 
IntPtr handle = client.Client.Handle; //returns a handle to the connection 

然后,所有你需要做的是存储在一个哈希表,并通过它遍历,寻找可用的数据。当您检测到某个连接的线路上的数据时,将其保存并重新发送到表格中的其他客户端。

请记住确保您使用此多线程,以便在一个客户端上收听请求不会阻止其他客户端上的任何发送或接收功能!

我已经添加了一些代码在这里你应该能够一起工作(测试了它在我的系统)

private void HandleClients(object newClient) 
     { 
      //check to see if we are adding a new client, or just iterating through existing clients 
      if (newClient != null) 
      { 
       TcpClient newTcpClient = (TcpClient)newClient; 

       //add this client to our list 
       clientList.Add(newTcpClient.Client.Handle, newTcpClient); 
       Console.WriteLine("Adding handle: " + newTcpClient.Client.Handle); //for debugging 
      } 

      //iterate through existing clients to see if there is any data on the wire 
      foreach (TcpClient tc in clientList.Values) 
      { 
       if (tc.Available > 0) 
       { 
        int dataSize = tc.Available; 
        Console.WriteLine("Received data from: " + tc.Client.Handle); //for debugging 

        string text = GetNetworkString(tc.GetStream()); 

        //and transmit it to everyone else 
        foreach (TcpClient otherClient in clientList.Values) 
        { 
         if (tc.Client.Handle != otherClient.Client.Handle) 
         { 
          Send(otherClient.GetStream(), text); 
         } 
        } 
       } 
      } 
     } 

     public void Send(NetworkStream ns, string data) 
     { 
      try 
      { 
       byte[] bdata = GetBytes(data, Encoding.ASCII); 
       ns.Write(bdata, 0, bdata.Length); 
      } 
      catch (Exception ex) 
      { 
       System.Diagnostics.Debug.WriteLine(ex.Message); 
      } 
     } 

     protected string GetNetworkString(NetworkStream ns) 
     { 
      if (ns.CanRead) 
      { 
       string receivedString; 
       byte[] b = GetNetworkData(ns); 

       receivedString = System.Text.Encoding.UTF8.GetString(b); 
       log.Info("Received string: " + receivedString); 

       return receivedString; 
      } 
      else 
       return null; 
     } 

     protected byte[] GetNetworkData(NetworkStream ns) 
     { 
      if (ns.CanRead) 
      { 
       log.Debug("Data detected on wire..."); 
       byte[] b; 
       byte[] myReadBuffer = new byte[1024]; 
       MemoryStream ms = new MemoryStream(); 
       int numberOfBytesRead = 0; 

       // Incoming message may be larger than the buffer size. 
       do 
       { 
        numberOfBytesRead = ns.Read(myReadBuffer, 0, myReadBuffer.Length); 
        ms.Write(myReadBuffer, 0, numberOfBytesRead); 
       } 
       while (ns.DataAvailable); 

       //and get the full message 
       b = new byte[(int)ms.Length]; 
       ms.Seek(0, SeekOrigin.Begin); 
       ms.Read(b, 0, (int)ms.Length); 
       ms.Close(); 

       return b; 
      } 
      else 
       return null; 
     } 

你会想从检查看是否有主线程中调用HandleClients有没有挂起的请求,并且运行在一个循环上。

相关问题