C#使用Socket向所有客户端发送消息

时间:2018-07-10 03:20:42

标签: c# sockets tcp-ip

我的目标是从服务器向连接的客户端发送消息。该代码有效,但是唯一的问题是,它只能将消息发送给发送命令的客户端。我需要的是接收其他客户端的消息。我在youtube上看到了这段代码,并做了一些调整。请在下面找到。

服务器代码

class Program
    {
        private static readonly Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        private static readonly List<Socket> clientSockets = new List<Socket>();
        private const int BUFFER_SIZE = 2048;
        private const int PORT = 100;
        private static readonly byte[] buffer = new byte[BUFFER_SIZE];

        static void Main(string[] args)
        {
            Console.Title = "Server";
            SetupServer();
            Console.ReadLine(); // When we press enter close everything
            CloseAllSockets();
        }


        private static void SetupServer()
        {
            Console.WriteLine("Setting up server...");
            serverSocket.Bind(new IPEndPoint(IPAddress.Any, PORT));
            serverSocket.Listen(0);
            serverSocket.BeginAccept(AcceptCallback, null);
            Console.WriteLine("Server setup complete");
        }

        /// <summary>
        /// Close all connected client (we do not need to shutdown the server socket as its connections
        /// are already closed with the clients).
        /// </summary>
        private static void CloseAllSockets()
        {
            foreach (Socket socket in clientSockets)
            {
                socket.Shutdown(SocketShutdown.Both);
                socket.Close();
            }

            serverSocket.Close();
        }

        private static void AcceptCallback(IAsyncResult AR)
        {
            Socket socket;

            try
            {
                socket = serverSocket.EndAccept(AR);
            }
            catch (ObjectDisposedException) // I can not seem to avoid this (on exit when properly closing sockets)
            {
                return;
            }

            clientSockets.Add(socket);
            socket.BeginReceive(buffer, 0, BUFFER_SIZE, SocketFlags.None, ReceiveCallback, socket);
            Console.WriteLine("{0}", socket.RemoteEndPoint + " connected...");
            serverSocket.BeginAccept(AcceptCallback, null);
        }

        private static void ReceiveCallback(IAsyncResult AR)
        {
            Socket current = (Socket)AR.AsyncState;
            int received;

            try
            {
                received = current.EndReceive(AR);
            }
            catch (SocketException)
            {
                Console.WriteLine("Client forcefully disconnected");
                // Don't shutdown because the socket may be disposed and its disconnected anyway.
                current.Close();
                clientSockets.Remove(current);
                return;
            }

            byte[] recBuf = new byte[received];
            Array.Copy(buffer, recBuf, received);
            string text = Encoding.ASCII.GetString(recBuf);
            Console.WriteLine("Received Text: " + text);

            if (text.ToLower() == "meeting") // Client requested time
            {
                foreach (Socket socket in clientSockets)
                {
                    //current = socket;
                    string message = "meeting";
                    byte[] data = Encoding.ASCII.GetBytes(message);
                    socket.Send(data);
                    //socket.BeginSend(data, 0, data.Length, SocketFlags.None, null, null);
                    Console.WriteLine("Meeting invite sent to " + socket.RemoteEndPoint);
                }

            }
            else if (text.ToLower() == "exit") // Client wants to exit gracefully
            {
                // Always Shutdown before closing
                Console.WriteLine(current.RemoteEndPoint + " disconnected");
                current.Shutdown(SocketShutdown.Both);
                current.Close();
                clientSockets.Remove(current);
                return;
            }
            else
            {
                Console.WriteLine("Invalid request");
                byte[] data = Encoding.ASCII.GetBytes("Invalid request");
                current.Send(data);
                Console.WriteLine("Warning Sent");
            }


            current.BeginReceive(buffer, 0, BUFFER_SIZE, SocketFlags.None, ReceiveCallback, current);
        }


    }

客户代码

namespace TCP_Client {
    public partial class frmTCPClient : Form
    {
        private readonly Socket ClientSocket = new Socket
            (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        private const int PORT = 100;
        private byte[] buffer;
        private string message { get; set; }
        public string serverMessage { get; set; }

        public frmTCPClient()
        {
            InitializeComponent();
        }

        private void frmTCPClient_Load(object sender, EventArgs e)
        {
            ConnectToServer();
            //UpdateControls();
        }

        private void UpdateControls()
        {
            lblMessage.Text = message;
            //txtFromServer.Text = serverMessage;
        }

        private void ConnectToServer()
        {
            int attempts = 0;

            while (!ClientSocket.Connected)
            {
                try
                {
                    attempts++;
                    //lblMessage.Text = "Connection attempt " + attempts;
                    // Change IPAddress.Loopback to a remote IP to connect to a remote host.
                    //ClientSocket.Connect(IPAddress.Loopback, PORT);
                    ClientSocket.Connect("172.20.110.129", PORT);
                }
                catch (SocketException ex)
                {
                    MessageBox.Show(ex.Message + Environment.NewLine + "Connection attempt " + attempts);
                }
            }

            message = "Connected";
        }

        private void RequestLoop()
        {
            while (true)
            {
                SendRequest("");
                ReceiveResponse();
            }
        }

        private void SendRequest(string text)
        {
            string request = text;
            SendString(request);

            if (request.ToLower() == "exit")
            {
                Exit();
            }
        }

        /// <summary>
        /// Sends a string to the server with ASCII encoding.
        /// </summary>
        private void SendString(string text)
        {
            try
            {
                byte[] buffer = Encoding.ASCII.GetBytes(text);
                ClientSocket.Send(buffer, 0, buffer.Length, SocketFlags.None);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            SendRequest(txtMessage.Text);
            ReceiveResponse();
            UpdateControls();
        }


        private void Exit()
        {
            SendString("exit"); // Tell the server we are exiting
            ClientSocket.Shutdown(SocketShutdown.Both);
            ClientSocket.Close();
            Environment.Exit(0);
        }

        public void ReceiveResponse()
        {
            var buffer = new byte[2048];
            try
            {
                if (buffer.ToString().Length == 2048) return;
                int received = ClientSocket.Receive(buffer, SocketFlags.None);
                if (received == 0) return;
                var data = new byte[received];
                Array.Copy(buffer, data, received);
                string text = Encoding.ASCII.GetString(data);
                txtFromServer.Text += text + System.Environment.NewLine;
                //MessageBox.Show(text);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                return;
            }
        }

        private void frmTCPClient_FormClosed(object sender, FormClosedEventArgs e)
        {
            Exit();

        }
    } }

更新

 foreach (object obj in clientSockets) 
 { 
    string message = "meeting"; 
    byte[] data = Encoding.ASCII.GetBytes(message); 
    Socket socket = (Socket)obj; 
    socket.Send(data); 
    Console.WriteLine("Meeting invite sent to " + socket.RemoteEndPoint);
  } 

图片

enter image description here

0 个答案:

没有答案