简体   繁体   English

异步服务器套接字示例

[英]Asynchronous Server Socket Example

I found this code of Asynchronous Server Socket Example and i am trying to get the data out from the thread where i receive info to update a textbox, but i can't just use a simple string. 我找到了异步服务器套接字示例的这段代码,我试图从接收信息以更新文本框的线程中获取数据,但是我不能只使用简单的字符串。 I've tried something called Control.Invoke Method (Delegate, Object[]) to update it but when the program gets to the form1.Invoke(form1.updateTextBox, content); 我已经尝试了一种称为Control.Invoke Method (Delegate, Object[])来更新它,但是当程序进入到form1.Invoke(form1.updateTextBox, content); i get this error: 我收到此错误:

Invoke or BeginInvoke cannot be called on a control until the window handle has been created.

The sad part is the MessageBox is working and displays the data I receive. 可悲的是,MessageBox正在运行并显示我收到的数据。

Here is the code: 这是代码:

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 
using System.Net; 
using System.Net.Sockets;
using System.Threading;

namespace Stream_Socket_Listener {
    public partial class Form1 : Form
    {
        public delegate void updateTextBoxDelegate(String textBoxString); // delegate 
        public updateTextBoxDelegate updateTextBox;
        void updateTextBox1(string str)
        {
            textBox1.Text = str;
        }
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e) { }

        private void button1_Click(object sender, EventArgs e)
        {
            updateTextBox = new updateTextBoxDelegate(updateTextBox1);
            AsynchronousSocketListener.StartListening();
        }

    }

    // State object for reading client data asynchronously
    public class StateObject
    {
        // Client socket.
        public Socket workSocket = null;
        // Size of receive buffer.
        public const int BufferSize = 1024;
        // Receive buffer.
        public byte[] buffer = new byte[BufferSize];
        // Received data string.
        public StringBuilder sb = new StringBuilder();
    }

    public class AsynchronousSocketListener
    {
        // Thread signal.
        public static ManualResetEvent allDone = new ManualResetEvent(false);

        public AsynchronousSocketListener() {  }

        public static void StartListening()
        {
            // Data buffer for incoming data.
            byte[] bytes = new Byte[1024];

            // Establish the local endpoint for the socket.
            // The DNS name of the computer
            // running the listener is "host.contoso.com".
            IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());
            IPAddress ipAddress = ipHostInfo.AddressList[0];
            IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 
              11000);

            // Create a TCP/IP socket.
            Socket listener = new Socket(AddressFamily.InterNetwork,
            SocketType.Stream, ProtocolType.Tcp);

            // Bind the socket to the local endpoint and listen for incoming                 
            // connections.
            try
            {
                listener.Bind(localEndPoint);
                listener.Listen(100);

                while (true)
                {
                    // Set the event to nonsignaled state.
                    allDone.Reset();

                    // Start an asynchronous socket to listen for connections.
                    Console.WriteLine("Waiting for a connection...");
                    listener.BeginAccept(new AsyncCallback(AcceptCallback),listener);

                    // Wait until a connection is made before continuing.
                    allDone.WaitOne();
                }

            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }

            Console.WriteLine("\nPress ENTER to continue...");
            Console.Read();
        }

        public static void AcceptCallback(IAsyncResult ar)
        {
            // Signal the main thread to continue.
            allDone.Set();

            // Get the socket that handles the client request.
            Socket listener = (Socket)ar.AsyncState;
            Socket handler = listener.EndAccept(ar);

            // Create the state object.
            StateObject state = new StateObject();
            state.workSocket = handler;
            handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
            new AsyncCallback(ReadCallback), state);
        }    

        public static void ReadCallback(IAsyncResult ar)
        {   String content = String.Empty;
            // Retrieve the state object and the handler socket
            // from the asynchronous state object.
            StateObject state = (StateObject)ar.AsyncState;
            Socket handler = state.workSocket;

            // Read data from the client socket.
            int bytesRead = handler.EndReceive(ar);

            if (bytesRead 0)
            {
                // There might be more data, so store the data received so far.
                state.sb.Append(Encoding.ASCII.GetString(
                state.buffer, 0, bytesRead));

                // Check for end-of-file tag. If it is not there, read
                // more data.
                content = state.sb.ToString();
                if (content.IndexOf("<EOF>") -1)
                {
                    // All the data has been read from the
                    // client. Display it on the console.
                    MessageBox.Show("Read " + content.Length + " bytes from socket. \n >Data" +  content);
                    Form1 form1 = new Form1();
                    Application.DoEvents();
                    form1.Invoke(form1.updateTextBox, content);
                    // Echo the data back to the client.
                    Send(handler, content);
                }
                else
                {
                    // Not all data received. Get more.
                    handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                    new AsyncCallback(ReadCallback), state);
                }
            }
        }
        private static void Send(Socket handler, String data)
        {
            // Convert the string data to byte data using ASCII encoding.
            byte[] byteData = Encoding.ASCII.GetBytes(data);

            // Begin sending the data to the remote device.
            handler.BeginSend(byteData, 0, byteData.Length, 0,
            new AsyncCallback(SendCallback), handler);
        }

        private static void SendCallback(IAsyncResult ar)
        {
            try
            {
                // Retrieve the socket from the state object.
                Socket handler = (Socket)ar.AsyncState;

                // Complete sending the data to the remote device.
                int bytesSent = handler.EndSend(ar);
                MessageBox.Show("Sent "+ bytesSent+ " bytes to client.");

                handler.Shutdown(SocketShutdown.Both);
                handler.Close();

            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }
    } 
}

I think your problem is because you are invoking the form's method before the form is fully created. 我认为您的问题是因为在完全创建表单之前调用了表单的方法。 Try creating the form beforehand and ignore those calls until the form is ready. 尝试事先创建表单,然后忽略这些调用,直到表单准备就绪为止。 Additionally, you might need to do something like this: 此外,您可能需要执行以下操作:

            if (InvokeRequired)
            {
                Invoke(new MethodInvoker(addMsg));
            }
            else
            {
                updateTextBox(content)
            }

To avoid issues due to invoke a method from a different thread. 为了避免由于从其他线程调用方法而导致的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM