客户端有个启动访问服务端的按钮,点击第一次是没有问题,但是点击第二次就遇到了问题,报
异常:遇到无法访问已释放的对象 System.Net.Sockets。现在怀疑是服务端的异步发送
引起的,handler.Shutdown(SocketShutdown.Both);handler.Close();客户端没有接收到传来的数据,为null,汇报异常,客户端报异常的代码我已经加红,请各位帮我看看咋回事,我不知道咋改了。
服务端:
Thread newThread;
        public static ManualResetEvent allDone = new ManualResetEvent(false);        public delegate void SetRichTextBoxReceiveCallback(string str);
        public SetRichTextBoxReceiveCallback setRichTextBoxReceiveCallback;
        private void SetRichTextBoxReceive(string str)
        {
            if (rtb_Content.InvokeRequired)
            {
                setRichTextBoxReceiveCallback = new SetRichTextBoxReceiveCallback(SetRichTextBoxReceive);
                rtb_Content.Invoke(setRichTextBoxReceiveCallback, str);
            }
            else
            {
                rtb_Content.AppendText(str);
            }
        }        private void btn_Start_Click(object sender, EventArgs e)
        {
            setRichTextBoxReceiveCallback = new SetRichTextBoxReceiveCallback(SetRichTextBoxReceive);
            ThreadStart ts = new ThreadStart(acceptConnect);
            newThread = new Thread(ts);
            newThread.Start();
        }        private void btn_Click(object sender, EventArgs e)
        {
            //newThread.Abort();
            System.Environment.Exit(0); 
        }        /// <summary>
        /// 开启一个socket监听线程
        /// </summary>
        private void acceptConnect()
        {
            IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8090);
            Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            // 绑定端口,并监听发起的连接请求。
            try
            {
                listener.Bind(endPoint);
                listener.Listen(100);
                while (true)
                {
                    // Set the event to nonsignaled state.
                    allDone.Reset();
                    // Start an asynchronous socket to listen for connections.
                    SetRichTextBoxReceive("等待客户端连接请求中......\n");
                    listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
                    // Wait until a connection is made before continuing.
                    allDone.WaitOne();
                }
            }
            catch (Exception ex)
            {
                SetRichTextBoxReceive(ex.Message.ToString());
            }
        }        /// <summary>
        /// 接收连接请求
        /// </summary>
        /// <param name="ar"></param>
        public 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。
            StateObject state = new StateObject();
            state.workSocket = handler;
            handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
        }        /// <summary>
        /// 读取连接请求
        /// </summary>
        /// <param name="ar"></param>
        private 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. 
                    SetRichTextBoxReceive("Read " + content.Length + " bytes from socket.\nData:" + content + ".\n");
                    // 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 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);
        }        public  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);
                rtb_Content.Invoke(setRichTextBoxReceiveCallback, "Sent " + bytesSent + " bytes to client.\n");
                handler.Shutdown(SocketShutdown.Both);
                handler.Close();
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

解决方案 »

  1.   

    客户端:
    Thread newThread;
            Socket client;
            // The port number for the remote device.
            private const int port = 8090;        // ManualResetEvent instances signal completion.
            private static ManualResetEvent connectDone = new ManualResetEvent(false);
            private static ManualResetEvent sendDone = new ManualResetEvent(false);
            private static ManualResetEvent receiveDone = new ManualResetEvent(false);        public delegate void SetRichTextBoxReceiveCallback(string str);
            public SetRichTextBoxReceiveCallback setRichTextBoxReceiveCallback;
            private void SetRichTextBoxReceive(string str)
            {
                if (rtb_Content.InvokeRequired)
                {
                    setRichTextBoxReceiveCallback = new SetRichTextBoxReceiveCallback(SetRichTextBoxReceive);
                    rtb_Content.Invoke(setRichTextBoxReceiveCallback, str);
                }
                else
                {
                    rtb_Content.AppendText(str);
                }
            }        // The response from the remote device.
            private static string response = string.Empty;        private void btn_Request_Click(object sender, EventArgs e)
            {
                // Connect to a remote device.
                try
                {
                    if (newThread != null)
                    {
                        newThread.Abort();
                    }
                    ThreadStart ts = new ThreadStart(acceptConnect);
                    newThread = new Thread(ts);
                    newThread.Start();
                }
                catch (Exception ex)
                {
                    SetRichTextBoxReceive(ex.Message.ToString() + "\n");
                }
            }        private void acceptConnect()
            {
                // Establish the remote endpoint for the socket.The name of the remote device is "127.0.0.1".
                IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8090);
                
                // Create a TCP/IP socket.
                //if (client == null && client.Connected)
                //{
                client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
                //}
                
                // Connect to the remote endpoint.
                client.BeginConnect(endPoint, new AsyncCallback(ConnectCallback), client);
                connectDone.WaitOne();
                
                // Send test data to the remote device.
                Send(client, "This is a test<EOF>");
                sendDone.WaitOne();
                
                // Receive the response from the remote device.
                Receive(client);
                receiveDone.WaitOne();
                
                // Write the response to the console.
                SetRichTextBoxReceive("Response received : " + response + ".\n");
                
                // Release the socket.
                client.Shutdown(SocketShutdown.Both);
                client.Close();
            }        private void ConnectCallback(IAsyncResult ar)
            {
                try
                {
                    // Retrieve the socket from the state object.
                    Socket client = (Socket)ar.AsyncState;
                    // Complete the connection.
                    client.EndConnect(ar);
                    SetRichTextBoxReceive("Socket connected to " + client.RemoteEndPoint.ToString() + ".\n");
                    // Signal that the connection has been made.
                    connectDone.Set();
                }
                catch (Exception ex)
                {
                    SetRichTextBoxReceive(ex.Message.ToString() + "\n");
                }
            }        private void Receive(Socket client)
            {
                try
                {
                    // Create the state object.
                    StateObject state = new StateObject();
                    state.workSocket = client;
                    // Begin receiving the data from the remote device.
                    client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
                }
                catch (Exception ex)
                {
                    SetRichTextBoxReceive(ex.Message.ToString() + "\n");
                }
            }        private void ReceiveCallback(IAsyncResult ar)
            {
                try
                {
                    // Retrieve the state object and the client socket from the asynchronous state object.
                    StateObject state = (StateObject)ar.AsyncState;
                    Socket client = state.workSocket;
                    // Read data from the remote device.
                    int bytesRead = client.EndReceive(ar);
                    if (bytesRead > 0)
                    {
                      private void Send(Socket client, 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.
                client.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), client);
            }        private void SendCallback(IAsyncResult ar)
            {
                try
                {
                    // Retrieve the socket from the state object
                    Socket client = (Socket)ar.AsyncState;
                    // Complete sending the data to the remote device.
                    int bytesSent = client.EndSend(ar);
                    SetRichTextBoxReceive("Sent " + bytesSent + " bytes to server.\n");
                    // Signal that all bytes have been sent.
                    sendDone.Set();
                }
                catch (Exception ex)
                {
                    SetRichTextBoxReceive(ex.Message.ToString() + "\n");
                }
            }         // There might be more data, so store the data received so far.
                        state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));
                        // Get the rest of the data.
                        client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
                    }
                    else
                    {
                        // All the data has arrived; put it in response.
                        if (state.sb.Length > 1)
                        {
                            response = state.sb.ToString();
                            // Signal that all bytes have been received.
                            receiveDone.Set();
                        }
                    }
                }
                catch (Exception ex)
                {
                    SetRichTextBoxReceive(ex.Message.ToString() + "\n");
                }
            } 
      

  2.   

    我晕....  你这代码叫人怎么看啊.这么长.. 还不按代码格式去发int i = 10;
      

  3.   

    都不用看你代码
    ---------------
    客户端有个启动访问服务端的按钮,点击第一次是没有问题,但是点击第二次就遇到了问题,报
    异常:遇到无法访问已释放的对象 System.Net.Sockets。
    ---------------这说明 server端 或者 client 在做了第1次的交互之后 把socket通道关闭了.
    所以你第2次应该重新new socket对象,并且重新连接.按上面思路改就行了,也很简单.
    但如果非要做 '长连接'的话,那就还是学点socket基础吧, 没基础咋弄都白搭.
      

  4.   

    高人,还在不?我还有个问题请教,长连接指的什么?
    我的貌似属于长连接不?
    http://topic.csdn.net/u/20110823/15/6e02718d-fedb-475e-b142-132dcb9634e4.html
      

  5.   

    private void btn_Start_Click(object sender, EventArgs e)
      {
      setRichTextBoxReceiveCallback = new SetRichTextBoxReceiveCallback(SetRichTextBoxReceive);
      ThreadStart ts = new ThreadStart(acceptConnect);
      newThread = new Thread(ts);
      newThread.Start();
      }你把这个 TS 定义到全局变量里看看
      

  6.   

    高人不敢当.你贴我回过..  你代码太长,还没有缩进格式.... 
    而且我还说错了,开始还以为你是要架server. 后来才知道是client; client 网上代码一抓一大把..  你搜索下呀.
    长连接就是 这个socket通道 建立之后双方都不 close; 你那个应该是长连接.
    没有其他特别约定.是相对于 http 这样短连接模式所有有长连接这样一说.
      

  7.   

    谢谢各位的热心帮助,刚学socket,看了段时间的书和资料,开始实际编码了遇到不少问题
      

  8.   


    不谢,如果我讲的有用记得给我加分,如果还想学习去看我刚发的帖子,对你应该有些帮助http://topic.csdn.net/u/20110823/15/6e02718d-fedb-475e-b142-132dcb9634e4.html
      

  9.   

    int i=0 在那个地方改?
      

  10.   


    讲的都对的,我的疑问就是登录不能完全成功,成功率和delphi相比,比较低,很费解