接收多个不同的消息TcpListener C# [英] Receive multiple different messages TcpListener C#

查看:91
本文介绍了接收多个不同的消息TcpListener C#的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Hey guys I have been trying to learn how to send some simple text messages between client server using TcpListener and sockets. I have read many threads that appear to be showing how to read the _Buffer in lets say a loop to ensure the whole message is read. However, I can't seem to figure out how to get the second message after the first one is received. I can connect to the server just fine and I can get the first message just fine. However, if I hit the send button on my Client again no message gets to the server. Here is my code:

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

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

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: ----------------------------------------------------

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

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

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

}

如果有人能解释如何做到这一点,我将不胜感激,我将不胜感激.我在使用任务和线程方面确实有一点经验,这是我需要做的事情吗?我只是想对此有所了解,所以我可以开始学习它.如果任何人有您认为可以帮助的建议或示例,请分享.

I would greatly appreciate if someone could explain how to make this so I can get more then one message. I do have a little experience in using Tasks and threading, is that something I need to do? I'm just trying to get a grasp on this so I can start learning it. If anyone has any recommendations or examples that you think could help please do share.

推荐答案

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

While the client is still connected to the server, don't close the socket on the server app deliberately. As you must keep alive the connection to receive another message, repeat the receive function call. If there is no data sent from the client, the Receive() function call will automatically block your current thread to wait for available data. If you click send message on the client application again, the data will be available for the server and will unblock that blocking part on the server app.

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

Your server application might be blocking the UI thread on the AcceptSocket() and Receive() part. When the StartServer button is clicked, your server window (UI) might become not responding because of no incoming connection available and you cannot see messages on your listStatus control. Thus, it is better to put those pieces of Socket code to run on a seperate thread in order not to block the UI thread. To work on the UI component from the seperate thread, a thread-safe UI manipulation is required to do so.

这是我所做的更改:

服务器

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.");
        }
    }
}

这篇关于接收多个不同的消息TcpListener C#的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆