首页 文章

套接字编程:服务器/客户端和线程使用

提问于
浏览
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?

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 ,该线程检查是否有任何待处理请求,并在循环上运行 .

相关问题