接收多个不同的消息TcpListener C#

时间:2014-01-12 06:53:03

标签: c# multithreading sockets tcp chat

嘿伙计们我一直在努力学习如何使用TcpListener和套接字在客户端服务器之间发送一些简单的文本消息。我已经阅读了许多线程,这些线程似乎显示了如何读取_Buffer,让我们说一个循环以确保读取整个消息。但是,我似乎无法弄清楚如何在收到第一条消息后获取第二条消息。我可以很好地连接到服务器,我可以得到第一条消息。但是,如果我再次点击我的客户端上的发送按钮,则没有消息到达服务器。这是我的代码:

// SERVER APPLICATION: -----------------------------------------------

namespace TCP_Server { public partial class Form1 : Form { public Form1() { InitializeComponent(); }

    private void btnStartServer_Click(object sender, EventArgs e)
    {
        // Define the TCP Listner:
        TcpListener _listner = new TcpListener(IPAddress.Parse("127.0.0.1"), 7777);

        // Start The Listner:
        _listner.Start();

        //Show the server is now listening:
        listStatus.Items.Add("Server started - Listening on port 7777");

        //Create a socket to accept - This is a Blocking Call:
        Socket _sock = _listner.AcceptSocket();

        //When Client Connects show server has accepted the socket:
        listStatus.Items.Add("User from IP " + _sock.RemoteEndPoint);

        while (_sock.Connected)
        {

            // Create Byte to Receive Data:
            byte[] _Buffer = new byte[1024];

            // Create integer to hold how large the Data Received is:
            int _DataReceived = _sock.Receive(_Buffer);

            // Lets Server Know Message is Received:
            listStatus.Items.Add("Message Received...");

            // Convert Buffer to a String:
            string _Message = Encoding.ASCII.GetString(_Buffer);

            // Post Message to the Server Window:
            listStatus.Items.Add(_Message);

            _sock.Close();
        }
    }
}

}

// CLIENT APPLICATION: ----------------------------------------------------

namespace TCP__Client { public partial class Form1 : Form { public Form1() { InitializeComponent(); }

// Defind the TCP Client: TcpClient _Client = new TcpClient(); private void btnConnect_Click(object sender, EventArgs e) { // Connect the TCP Client: _Client.Connect("127.0.0.1", 7777); // Show the Client has Connected: listStatus.Items.Add("Connected to Server 127.0.0.1"); } private void btnSend_Click(object sender, EventArgs e) { while (_Client.Connected) { // Create a Stream: Stream _Stream = _Client.GetStream(); // Create Instance of an Encoder: ASCIIEncoding _Asc = new ASCIIEncoding(); byte[] _Buffer = new byte[1024]; // Create Buffer to Send Message: _Buffer = _Asc.GetBytes(txtMessage.Text); // Show Client is Sending Message: listStatus.Items.Add("Tranmitting Message..."); // Write Message to the Stream: _Stream.Write(_Buffer, 0, _Buffer.Length); // Close Stream _Stream.Close(); _Stream.Dispose(); } } }

}

如果有人能解释如何做到这一点,我会非常感激,这样我就可以得到更多信息。我在使用任务和线程方面有一点经验,我需要做些什么?我只是想抓住这个,所以我可以开始学习它。如果有人有任何您认为有帮助的建议或示例,请分享。

1 个答案:

答案 0 :(得分:0)

虽然客户端仍然连接到服务器,但请不要故意关闭服务器应用程序上的套接字。由于您必须保持连接以接收另一条消息,因此请重复接收函数调用。如果没有从客户端发送数据,则Receive()函数调用将自动阻止当前线程等待可用数据。如果再次单击客户端应用程序上的发送消息,则数据将可用于服务器,并将取消阻止服务器应用程序上的阻止部分。

您的服务器应用程序可能阻止了AcceptSocket()和Receive()部分的UI线程。单击StartServer按钮时,由于没有可用的传入连接,您的服务器窗口(UI)可能无法响应,并且您无法在listStatus控件上看到消息。因此,最好将这些Socket代码段放在单独的线程上运行,以免阻塞UI线程。要从单独的线程处理UI组件,需要进行线程安全的UI操作。

以下是我所做的更改:

服务器

namespace Tcp_Server
{
    public partial class Form1 : Form
    {
        delegate void AddTextCallback(string text);

        public Form1()
        {
            InitializeComponent();
        }

        private void btnStartServer_Click(object sender, EventArgs e)
        {
            ThreadPool.QueueUserWorkItem(new WaitCallback(ServerHandler));
        }

        private void ServerHandler(object args)
        {
            TcpListener _listner = new TcpListener(IPAddress.Parse("127.0.0.1"), 7777);

            // Start The Listner:
            _listner.Start();

            //Show the server is now listening (Note: UI Thread-Safe is required):
            AddText("Server started - Listening on port 7777");

            //Create a socket to accept - This is a Blocking Call:
            Socket _sock = _listner.AcceptSocket();

            //When Client Connects show server has accepted the socket:
            AddText("User from IP " + _sock.RemoteEndPoint);

            while (_sock.Connected)
            {

                // Create Byte to Receive Data:
                byte[] _Buffer = new byte[1024];

                // Create integer to hold how large the Data Received is:
                int _DataReceived = _sock.Receive(_Buffer);

                if (_DataReceived == 0)
                {
                    // Socket has been shutdown by the client.
                    break;
                }

                // Lets Server Know Message is Received:
                AddText("Message Received...");

                // Convert Buffer to a String:
                string _Message = Encoding.ASCII.GetString(_Buffer);

                // Post Message to the Server Window:
                AddText(_Message);
            }

            _sock.Close();
            //When Client disconnect from the server:
            AddText("Client Disconnected.");

            _listner.Stop();
            AddText("Server Stop.");
        }


        private void AddText(string text)
        {
            // InvokeRequired required compares the thread ID of the 
            // calling thread to the thread ID of the creating thread. 
            // If these threads are different, it returns true. 
            if (this.listStatus.InvokeRequired)
            {
                AddTextCallback d = new AddTextCallback(AddText);
                this.Invoke(d, new object[] { text });
            }
            else
            {
                this.listStatus.Items.Add(text);
            }
        }
    }
}

客户端

namespace Tcp_Client
{
    public partial class Form1 : Form
    {
        // Defind the TCP Client:
        TcpClient _Client = null;
        Stream _Stream = null;

        public Form1()
        {
            InitializeComponent();
        }

        private void btnConnect_Click(object sender, EventArgs e)
        {
            _Client = new TcpClient();

            // Connect the TCP Client:
            _Client.Connect("127.0.0.1", 7777);

            // Show the Client has Connected:
            listStatus.Items.Add("Connected to Server 127.0.0.1");

            // Create a Stream:                
            _Stream = _Client.GetStream();
        }

        private void btnSend_Click(object sender, EventArgs e)
        {
            if (_Client.Connected)
            {
                // Create Instance of an Encoder:
                ASCIIEncoding _Asc = new ASCIIEncoding();

                byte[] _Buffer = new byte[1024];

                // Create Buffer to Send Message:
                _Buffer = _Asc.GetBytes(txtMessage.Text);

                // Show Client is Sending Message:
                listStatus.Items.Add("Tranmitting Message...");

                // Write Message to the Stream:
                _Stream.Write(_Buffer, 0, _Buffer.Length);
            }
        }

        private void btnDisconnect_Click(object sender, EventArgs e)
        {
            _Stream.Close();
            _Stream.Dispose();
            _Client.Close();
            listStatus.Items.Add("Disconnected from server.");
        }
    }
}