背景运行服务器与套接字连接

时间:2016-01-17 12:16:37

标签: c# sockets task

现在我有了这个:

[STAThread]
static void Main()
        {
            if (flag) //client view
                Application.Run(new Main_Menu());
            else
            {
                Application.Run(new ServerForm());
            }
        }

ServerForm.cs

 public partial class ServerForm : Form
    {
        public ServerForm()
        {
            InitializeComponent();
            BeginListening(logBox);
        }

        public void addLog(string msg)
        {
            this.logBox.Items.Add(msg);
        }

        private void button1_Click(object sender, EventArgs e)
        {

        }
        private async void BeginListening(ListBox lv)
        {
            Server s = new Server(lv);
            s.Start();
        }
    }

Server.cs

public class Server
    {
        ManualResetEvent allDone = new ManualResetEvent(false);
        ListBox logs;
        ///
        /// 
        /// Starts a server that listens to connections
        ///
        public Server(ListBox lb)
        {
            logs = lb;
        }
        public void Start()
        {
            Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            listener.Bind(new IPEndPoint(IPAddress.Loopback, 1440));
            while (true)
            {
                Console.Out.WriteLine("Waiting for connection...");
                allDone.Reset();
                listener.Listen(100);
                listener.BeginAccept(Accept, listener);
                allDone.WaitOne(); //halts this thread
            }
        }
        //other methods like Send, Receive etc.
}

我想运行我的ServerForm(它有ListBox来打印来自Server的消息)。我知道ListBox参数不起作用,但我无法在没有暂停Server的情况下运行ServerForm无限循环(我甚至无法移动窗口)。我也尝试使用Threads - 不幸的是它不起作用。

1 个答案:

答案 0 :(得分:2)

WinForms有一个叫做UI线程的东西。它是一个负责绘制和处理UI的线程。如果该线程忙于做某事,UI将停止响应。

常规套接字方法是阻塞的。这意味着除非套接字上发生了某些事情,否则它们不会将控制权返回给您的应用程序。因此,每次在UI线程上执行套接字操作时,UI都将停止响应,直到套接字方法完成。

要解决这个问题,您需要为套接字操作创建一个单独的线程。

new ByteBuddy()
  .subclass(Object.class)
  .defineField("foo", Void.class)
  .annotateField(annotationDescription)
  .make();

但是,所有UI操作必须在UI线程上进行。这样,如果您尝试从套接字线程更新public class Server { ManualResetEvent allDone = new ManualResetEvent(false); Thread _socketThread; ListBox logs; public Server(ListBox lb) { logs = lb; } public void Start() { _socketThread = new Thread(SocketThreadFunc); _socketThread.Start(); } public void SocketThreadFunc(object state) { Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); listener.Bind(new IPEndPoint(IPAddress.Loopback, 1440)); while (true) { Console.Out.WriteLine("Waiting for connection..."); allDone.Reset(); listener.Listen(100); listener.BeginAccept(Accept, listener); allDone.WaitOne(); //halts this thread } } //other methods like Send, Receive etc. } ,您将获得异常。

解决这个问题的最简单方法是使用Invoke