2013-03-25 58 views
0

我发现此代码的异步服务器套接字示例,我试图从线程中获取数据,其中我收到信息来更新文本框,但我不能只使用一个简单的字符串。我试过一种叫Control.Invoke Method (Delegate, Object[])更新,但是当程序获取到form1.Invoke(form1.updateTextBox, content);我得到这个错误:异步服务器套接字示例

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

不幸的是MessageBox的工作,并显示我接收到的数据。

下面是代码:

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()); 
      } 
     } 
    } 
} 

回答

0

我觉得你的问题是,因为要调用的窗体的方法完全创建表单之前。尝试预先创建表单并忽略这些调用,直到表单准备就绪。此外,您可能需要执行以下操作:

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

为了避免因调用另一个线程中的方法而引发的问题。