首页 新闻 会员 周边 捐助

socket通讯,由于线程退出或应用程序请求,以放弃I/O操作。”急!

0
悬赏园豆:50 [已关闭问题] 关闭于 2011-12-29 15:45

private IPAddress myIp;
        private IPEndPoint myserver;
        private Socket sock;
        private Socket handler;
        private static ManualResetEvent Done = new ManualResetEvent(false);
        protected void Page_Load(object sender, EventArgs e)
        {

        }
        //监听
        #region
        /// <summary>
        /// 监听服务器端口
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        #endregion
        protected void Button1_Click(object sender, EventArgs e)
        {
            try
            {
                myIp =IPAddress.Parse(TextBox3.Text);
            }
            catch(Exception E)
            {
                show(E.Message);
            }
            try
            {
                //服务器的IP和port
                myserver = new IPEndPoint(myIp,int.Parse(TextBox4.Text));
                //实例化一个SOCKET
                sock = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
                //关联服务器和socket
                sock.Bind(myserver);
                //使socket处于侦听状态
                sock.Listen(50);
                status.Text = "主机" + TextBox3.Text + "端口" + TextBox4.Text + "正在监听";

 

                //开启线程
                Thread thread = new Thread(new ThreadStart(listenfunction));
                thread.Start();
            }
            catch (Exception ee)
            {
                status.Text = ee.Message;
            }
        }

        #region
        /// <summary>
        /// 监听的工作线程的方法
        /// </summary>
        private void listenfunction()
        {
            while(true)
            {
                //ManualResetEvent复位
                Done.Reset();

                //开始接受请求连接
                sock.BeginAccept(new AsyncCallback(AcceptCallBack),sock);

                //等待信号
                Done.WaitOne();
            }
        }
        #endregion

        #region
        private void AcceptCallBack(IAsyncResult ar)
        {
            //允许继续等待!
            Done.Set();
            Socket listener = (Socket)ar.AsyncState;
            handler = listener.EndAccept(ar);

            StateObject state = new StateObject();
            state.worksocket = handler;
            status.Text = "与客户建立连接";


            try
            {
                byte[] bytedata = System.Text.Encoding.ASCII.GetBytes("准备完毕,可以通话!"+"\n\r");
               // handler.BeginSend(bytedata,0,bytedata.Length,0,new AsyncCallback(SendCallBack),handler);

            }
            catch(Exception e)
            {
                show(e.Message);
            }
            Thread threads = new Thread(new ThreadStart(rec));
            threads.Start();
        }
        #endregion

        #region
        /// <summary>
        /// 异步接收
        /// </summary>
        private void rec()
        {
            StateObject state = new StateObject();
            state.worksocket = handler;

            //开始异步接收

            handler.BeginReceive(state.buffer,0,StateObject.buffersize,0,new AsyncCallback(ReadCallBack),state);
        }
        #endregion
        #region
        /// <summary>
        /// 异步接受回调方法
        /// </summary>
        /// <param name="ar"></param>
        private void ReadCallBack(IAsyncResult ar)
        {
            StateObject state = (StateObject)ar.AsyncState;
            Socket TT = state.worksocket;

            int bytesRead = handler.EndSend(ar);
            state.sb.Append(System.Text.Encoding.ASCII.GetString(state.buffer,0,bytesRead));
            string content = state.sb.ToString();
            state.sb.Remove(0,content.Length);
            TextBox1.Text += content + "\r\n";
            TT.BeginReceive(state.buffer,0,StateObject.buffersize,0,new AsyncCallback(ReadCallBack),state);

        }
        #endregion
        #region
        /// <summary>
        /// 异步发送的回调方法
        /// </summary>
        /// <param name="ar"></param>
        private void SendCallBack(IAsyncResult ar)
        {
            try
            {
                handler = (Socket)ar.AsyncState;
                int bytesSent = handler.EndSend(ar);
            }
            catch
            {
                show(" !");
            }

        }
        #endregion

        #region
        /// <summary>
        /// 弹出脚本框
        /// </summary>
        /// <param name="str"></param>
        private void show(string str)
        {
            Page.ClientScript.RegisterStartupScript(this.GetType(),"","<script>alert('"+str+"')</script>");
        }
        #endregion

        #region
        /// <summary>
        /// 停止监听
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void Button3_Click(object sender, EventArgs e)
        {
            try
            {
                sock.Close();
                status.Text = "主机" + TextBox3.Text + "端口" + TextBox4.Text + "停止监听";
            }
            catch
            {
                show("监听尚未开始,关闭无效!");
            }
        }
        #endregion


        #region
        /// <summary>
        /// 发送数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void Button2_Click(object sender, EventArgs e)
        {
            try
            {
                byte[] bytedata = System.Text.Encoding.ASCII.GetBytes(TextBox2.Text+"\r\n");
                handler.BeginSend(bytedata,0,bytedata.Length,0,new AsyncCallback(SendCallBack),handler);
            }
            catch(Exception E)
            {
                show(E.Message);
            }
        }
       
        #endregion
    }

 

在异步接受回调方法的时候!这句总报错“int bytesRead = handler.EndSend(ar);”

报:由于线程退出或应用程序请求,以放弃I/O操作。”

吾洋天啸的主页 吾洋天啸 | 初学一级 | 园豆:157
提问于:2010-12-24 11:21
< >
分享
所有回答(3)
0

这个问题我也碰到了,这个异常我认定他为一个不稳定异常。

就你这里的逻辑进行分析:

 Thread threads = new Thread(new ThreadStart(rec));
            threads.Start();
       你的rc函数是这样调用的,而你rc函数的编写时使用了异步,也就是函数退出的时候 你的内部逻辑实际上是没有退出的。

这个是我对这个异常的理解。

在rc函数地步我等待了1分钟,结果 就报这个异常了, 你可以试试

姜小牙 | 园豆:248 (菜鸟二级) | 2011-01-10 23:14
0

加个东西就可以了,不用那个属性

吾洋天啸 | 园豆:157 (初学一级) | 2011-12-29 15:43
0


 //ManualResetEvent复位
 Done.Reset();

非常感觉,这个属性很重要,少了这个,只有第一次成功,之后又会报错!

canyeah | 园豆:202 (菜鸟二级) | 2013-07-04 10:33
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册