C# Socket Programming With Multiclients

时间:2017-05-16 09:24:44

标签: c# multithreading sockets

I am making a client-server program. There are two client forms and one server form. Program works perfect for 1v1 connection but the other machine can't connect when the one has connection with server. I want to make with multiclients.

Here the codes.

Server.cs

private TcpListener ConnectionListener;//variable needed to listen for connections
    private BinaryReader MessageReader;//variable for reading messages
    private BinaryWriter MessageWriter;//variable for writing messages
    private Socket ClientConnection = new Socket(System.Net.Sockets.AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//variable for holding the client connection
    private NetworkStream DataStream;//variable for keeping server and client in a stream and synchronized
    private Thread ListeningThread;//variable that is assigned to a thread listening for incoming connections and preventing the pc from blocking

    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_FormClosing(object sender, FormClosingEventArgs e)
    {
        System.Environment.Exit(System.Environment.ExitCode);//exit and close all threads and release all recources
    }

    //functions used for networks
    private void ListenForConnections()
    {
        //try listening with the given ip address
        try
        {
            ConnectionListener = new TcpListener(IPAddress.Parse(txt_Ip.Text), 80);//listen to given ip on port 80 allways
            ConnectionListener.Start();//start listening;
            ChangeTextBoxContent("Bağlantılar Dinleniyor.");
            ClientConnection = ConnectionListener.AcceptSocket();//wait untill client connects (blocking function) if connected return a socket 
            DataStream = new NetworkStream(ClientConnection);//initialize a stream 
            MessageReader = new BinaryReader(DataStream);//use reader within the stream
            MessageWriter = new BinaryWriter(DataStream);//use writer within the stream
            ChangeTextBoxContent("Bağlantı Alındı.");
            Thread acceptThread = new Thread(new ThreadStart(HandleConnection));
            acceptThread.Start();
            MessageReader.Close();//close the reader;
            MessageWriter.Close();//close the writer;
            DataStream.Close();//close the stream;
            ClientConnection.Close();//close thre connection
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.ToString());//signal the error in a message box
        }
    }
    private void HandleConnection()
    {
        string message;
        //loop until infinity
        do
        {
            //try reading from the data stream if anything went wrong with the connection break
            try
            {
                message = MessageReader.ReadString();//read message
                ChangeTextBoxContent(message);//call the function that manipulates text box from a thread and change the contents.
            }
            catch (Exception)
            {
                ChangeTextBoxContent("Bağlantı Kayboldu.");
                break;//get out of the while loop
            }
        } while (true);
    }
    private void ChangeTextBoxContent(string tx)
    {
        if (txt_mesajlar.InvokeRequired)//if the messages text box needs a delegate invoking
        {
            Invoke(new UpdateTextBox(ChangeTextBoxContent), new object[] { tx });
        }
        else
        {
            //if no invoking required then change
            txt_mesajlar.Text += tx + "\r\n";//concatinate the original with the given message and a new line
        }
    }

    private void btn_start_listen_Click(object sender, EventArgs e)
    {
        try
        {
            IPAddress.Parse(txt_Ip.Text);//
            ListeningThread = new Thread(new ThreadStart(ListenForConnections));//assign thread variable with the blocking function
            ListeningThread.Start();//start the thread that will wait for connections
        }
        catch (Exception)
        {
            MessageBox.Show("Yanlış Ip Adresi");//signal the error in a message box
        }
    }

And Clients' code

   private TcpClient Client;//variable needed to listen for connections
    private BinaryReader MessageReader;//variable for reading messages
    private BinaryWriter MessageWriter;//variable for writing messages
    private NetworkStream DataStream;//variable for keeping server and client in a stream and synchronized
    private Thread ClientThread;//variable that is assigned to a thread listening for incoming connections and preventing the pc from blocking

    public int MachineState = 0;   // active-passive state
    public int MachineStatus = 0;  // on-off state
    public string MachineName = "Cnc1";
    public int counterfortimerdebug = 0;
    public Form1()
    {
        InitializeComponent();

        MachineStatus = 1;  // Machine Opened

        try
        {
            MachineState = 1;
            IPAddress.Parse("127.0.0.1");
            ClientThread = new Thread(new ThreadStart(PerformConnection));
            ClientThread.Start();
        }
        catch (Exception Ex)
        {
            MessageBox.Show(Ex.ToString());
        }

    }


    private void Form1_Load(object sender, EventArgs e)
    {
        lb_gcodes.Items.Add("01000");
        lb_gcodes.Items.Add("T1 M6");
        lb_gcodes.Items.Add("G0 G90 G40 G21 G17 G94 G80");
        lb_gcodes.Items.Add("G54 X-75 Y-25 S500 M3");
        lb_gcodes.Items.Add("G43 Z100 H1");
        lb_gcodes.Items.Add("Z5");
        lb_gcodes.Items.Add("G1 Z-20 F100");
        lb_gcodes.Items.Add("X-50 M8");
        lb_gcodes.Items.Add("X0 Y50");
        lb_gcodes.Items.Add("X50 Y0");
        lb_gcodes.Items.Add("G0 Z100");
        lb_gcodes.Items.Add("M30");

    }

    private void Form1_FormClosing(object sender, FormClosingEventArgs e)
    {
        System.Environment.Exit(System.Environment.ExitCode);//exit and close all threads and release all recources
    }

    //network functions used
    private void PerformConnection()
    {

        try
        {
            Client = new TcpClient();
            ChangeTextBoxContent("Bağlanıyor......");
            Client.Connect(IPAddress.Parse("127.0.0.1"), 80);
            DataStream = Client.GetStream();
            MessageReader = new BinaryReader(DataStream);
            MessageWriter = new BinaryWriter(DataStream);
            MessageWriter.Write(MachineName + " " + "Bağlandı..");
            ChangeTextBoxContent("Bağlandı..");
            HandleConnection();
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.ToString());
        }
    }
    private void HandleConnection()
    {
        string message;
        //loop until infinity
        do
        {
            //try reading from the data stream if anything went wrong with the connection break
            try
            {
                message = MessageReader.ReadString();//read message
                ChangeTextBoxContent(message);//call the function that manipulates text box from a thread and change the contents.
            }
            catch (Exception ex)
            {
                ChangeTextBoxContent(ex.ToString());
                break;
            }
        } while (true);
    }
    private void ChangeTextBoxContent(string tx)
    {
        if (txt_mesajlar.InvokeRequired)
        {
            Invoke(new UpdateTextBox(ChangeTextBoxContent), new object[] { tx });
        }
        else
        {
            //if no invoking required then change
            txt_mesajlar.Text += tx + "\r\n";//concatinate the original with the given message and a new line
        }
    }

Thanks for any help.

2 个答案:

答案 0 :(得分:0)

只需更新方法并添加bool变量即可停止监听:

private void ListenForConnections()
{
while(!IsStopped)
    //try listening with the given ip address
    ....
}
}

答案 1 :(得分:0)

你可以看到我的班级具有相同的功能:

 public delegate void Message(string message, IPAddress from);
    public class Listener : IDisposable
    {
        private readonly TcpListener _tcp;
        private Message _OnRecieve;
        private Thread _listenThread;
        private bool IsStopped = false;
        public Listener(IPAddress ip, int port, Message f)
        {
            _tcp = new TcpListener(ip, port);
            _OnRecieve = f;
        }
        public void Start()
        {
            _listenThread = new Thread(ListenForClients);
            _listenThread.Start();
        }
        public void Stop()
        {
            if (_tcp != null)
            {
                _listenThread.Abort();
                _tcp.Stop();
                IsStopped = true;
            }
        }
        private void ListenForClients()
        {
            _tcp.Start();
            while (!IsStopped)
            {
                TcpClient client = _tcp.AcceptTcpClient();
                var clientThread = new Thread(HandleClientComm);
                clientThread.Start(client);
            }
        }
        private void HandleClientComm(object client)
        {
            ReadMessage((TcpClient)client);
        }
        void IDisposable.Dispose()
        {
            if (_tcp != null)
            {
                _listenThread.Abort();
                _tcp.Stop();
                IsStopped = true;
            }
        }
        private void ReadMessage(TcpClient client)
        {
            try
            {
                NetworkStream ns = client.GetStream();
                string msg = ... /// read message
                _OnRecieve(msg,client.(client.Client.RemoteEndPoint as IPEndPoint).Address;
                client.Close();  
            }
            catch (Exception exc)
            {

                client.Close();
                throw exc;
            }
        }
    }

和用法:

        public void NetworkGet(string s, System.Net.IPAddress ip)
        {
           // do anything
        }
        public Server()
        {
            listener = new Network.Listener(System.Net.IPAddress.Any, Properties.Main.Default.NetworkPort, NetworkGet);
            listener.Start();  
        }