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;



    }

我想写一个聊天程序,它有一个服务器和两个客户端。问题是,我无法通过服务器将来自客户端 1 的消息定向到客户端 2。服务器如何区分线程,以便将收到的消息从client1发送到client2?

4

1 回答 1

1

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

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,该线程检查是否有任何挂起的请求,并在循环中运行。

于 2012-12-21T20:46:42.277 回答