日期:2014-05-18  浏览次数:20724 次

新手求助:socket异步监听中怎么跟新窗体控件的信息?
我做了一个简单的socket服务器,监听客户端传来的消息。用的异步操作代码其实我并不是太懂,所以有一些地方很迷惑。我现在最不解的地方就是在ReceiveMessage(IAsyncResult ar)这个方法里面,在这里从客户端获取一些消息,然后根据判断做出回应。同时我还需要在回应的同时更新窗体上richTextBox1里的内容,就是把ReceiveMessage(IAsyncResult ar)方法里的Msg变量的值添加到富文本框中,可是在ReceiveMessage(IAsyncResult ar)方法中richTextBox1竟然不存在。。。。郁闷,求指教。。
C# code

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

namespace tcp服务器
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        static string Msg=null;
        private void button1_Click(object sender, EventArgs e)
        {
            var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            //将该socket绑定到主机上面的某个端口
            socket.Bind(new IPEndPoint(IPAddress.Any, 8888));

            //启动监听,并且设置一个最大的队列长度
            socket.Listen(10);
            richTextBox1.AppendText("Server is Lincening!");
            //开始接受客户端连接请求
           
            
                socket.BeginAccept(new AsyncCallback(ClientAccepted), socket);
                
                if (Msg != null)
                {
                    richTextBox1.AppendText(Msg);
                    Msg = null;
                }
        }
        public static void ClientAccepted(IAsyncResult ar)
        {

            var socket = ar.AsyncState as Socket;

            //这就是客户端的Socket实例,我们后续可以将其保存起来
            var client = socket.EndAccept(ar);

            //接收客户端的消息(这个和在客户端实现的方式是一样的)
            client.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveMessage), client);
            
            //准备接受下一个客户端请求
            socket.BeginAccept(new AsyncCallback(ClientAccepted), socket);
        }

        static byte[] buffer = new byte[1024];

        public static void ReceiveMessage(IAsyncResult ar)
        {
            try
            {
                var socket = ar.AsyncState as Socket;
                var length = socket.EndReceive(ar);
                //读取出来消息内容
                var message = Encoding.Unicode.GetString(buffer, 0, length);
                //显示消息
                //Console.WriteLine(message);
                string strFlog = message.Substring(0, 1);

                switch (int.Parse(strFlog))
                {
                    case 0:             //如果首字符为0,
                        {

                            socket.Send(Encoding.Unicode.GetBytes("{asdasd,asd}"));
                        } break;
                    case 1:
                        {
                            string megcontent = message.Substring(1, message.Length - 1);
                            Msg = megcontent + " 测试一在线......"+strFlog;//!
                        } break;
                    case 2:
                        {
                            string megcontent = message.Substring(1, message.Length - 1);
                            Msg = megcontent + " 测试2在线......"+strFlog;//!
                        } break;
                    default: Msg = "无效信息"; break;//!
                }
                socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveMessage), socket);        
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
           
        } 
    }
}



------解决方案--------------------
//3楼的委托忘记初始化了,应该是这样
//异步委托调用主线程的显示方法,回到UI主线程。
//先写个方法用于在窗体显示信息
public void ShowMsg(string msg)
{
? MessageBox.Show(msg);
}
//声明委托
delegate void mydelegate(string msg);

//在你的异步方法ReceiveMessage里调用主界面委托的方法
Form1.CheckForIllegalCrossThreadCalls = false;
Form1.BeginInvok