代码如下:using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;using BWU.LogisticsDept.Museum.Extension;namespace BWU.LogisticsDept.Museum.AsynchronousTcpSocket
{
    public class AsyncTcpClient : AsynchronousTcp, IAsyncTcpClient
    {
        private static ManualResetEvent connectDone = new ManualResetEvent(false);
        private static ManualResetEvent sendDone = new ManualResetEvent(false);
        private static ManualResetEvent receiveDone = new ManualResetEvent(false);        private IPEndPoint remoteEP;        private String response = String.Empty;
        private String logFileName;        public AsyncTcpClient(String remoteIP, Int32 remotePort,String logFileName)
            : base(remoteIP, remotePort)
        {
            this.logFileName = logFileName;            remoteEP = new IPEndPoint(IPAddress.Parse(IP), Port);
        }        public Boolean Sending(Byte[] sendBuff)
        {
            try
            {
                Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);                clientSocket.BeginConnect(remoteEP, new AsyncCallback(ConnectCallBack), clientSocket);
                connectDone.WaitOne();                Send(clientSocket, sendBuff);
                sendDone.WaitOne();                Receive(clientSocket);
                receiveDone.WaitOne();//程序在这里出现过长时间等待,加上超时设置可以暂时解决                clientSocket.Shutdown(SocketShutdown.Both);
                clientSocket.Close();
                GC.Collect();
                return true;
            }
            catch (Exception e)
            {
                e.SaveErrorLogToFile(logFileName);
                return false;
            }
        }        private void ConnectCallBack(IAsyncResult ar)
        {
            try
            {
                Socket clientSocket = (Socket)ar.AsyncState;                clientSocket.EndConnect(ar);
                connectDone.Set();
            }
            catch(Exception e)
            {
                e.SaveErrorLogToFile(logFileName);
            }
        }        private void Receive(Socket clientSocket)
        {
            try
            {
                StateObject state = new StateObject();                state.WorkSocket = clientSocket;
                clientSocket.BeginReceive(state.Buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(RecevieCallback), state);
            }
            catch (Exception e)
            {
                e.SaveErrorLogToFile(logFileName);
            }
        }        private void RecevieCallback(IAsyncResult ar)
        {
            try
            {
                StateObject state = (StateObject)ar.AsyncState;
                Socket clientSocket = state.WorkSocket;                Int32 bytesRead = clientSocket.EndReceive(ar);//这里出现异常:无法访问已释放的对象。对象名:“System.Net.Sockets.Socket”。                if (bytesRead > 0)
                {
                    state.StrBuilder.Append(Encoding.ASCII.GetString(state.Buffer, 0, bytesRead));
                    clientSocket.BeginReceive(state.Buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(RecevieCallback), state);
                }
                else
                {
                    if (state.StrBuilder.Length > 1)
                    {
                        response = state.StrBuilder.ToString();
                    }
                }                receiveDone.Set();
            }
            catch (Exception e)
            {
                e.SaveErrorLogToFile(logFileName);
            }
        }        private void Send(Socket clientSocket, Byte[] sendBuff)
        {
            clientSocket.BeginSend(sendBuff, 0, sendBuff.Length, 0, new AsyncCallback(SendCallback), clientSocket);//由于套接字没有连接并且(当使用一个 sendto 调用发送数据报套接字时)没有提供地址,发送或接收数据的请求没有被接受。
        }        private void SendCallback(IAsyncResult ar)
        {
            try
            {
                Socket clientSocket = (Socket)ar.AsyncState;                Int32 bytesSent = clientSocket.EndSend(ar);
                sendDone.Set();
            }
            catch (Exception e)
            {
                e.SaveErrorLogToFile(logFileName);
            }
        }
    }
}
主要出错的地方我写在代码注释上了,求高手帮助寻找问题,修改代码

解决方案 »

  1.   

                    Receive(clientSocket);
                    receiveDone.WaitOne();//程序在这里出现过长时间等待,加上超时设置可以暂时解决
    首先一点,你要确认服务器端是否能ping通,有否回应(最好用同步的TCP连上测测)。Int32 bytesRead = clientSocket.EndReceive(ar);//这里出现异常:无法访问已释放的对象。对象名:“System.Net.Sockets.Socket”。
    你前面有超时的设置,这个是否为空对象的判断是必须要加上的了。
      

  2.   

    之前的代码有点问题,现重贴:using System;
    using System.Net;
    using System.Net.Sockets;
    using System.Text;
    using System.Threading;using BWU.LogisticsDept.Museum.Extension;namespace BWU.LogisticsDept.Museum.AsynchronousTcpSocket
    {
        public class AsyncTcpClient : AsynchronousTcp, IAsyncTcpClient
        {
            private ManualResetEvent connectDone = new ManualResetEvent(false);
            private ManualResetEvent sendDone = new ManualResetEvent(false);
            private ManualResetEvent receiveDone = new ManualResetEvent(false);        private IPEndPoint remoteEP;        private String response = String.Empty;
            private String logFileName;        public AsyncTcpClient(String remoteIP, Int32 remotePort, String logFileName)
                : base(remoteIP, remotePort)
            {
                this.logFileName = logFileName;            remoteEP = new IPEndPoint(IPAddress.Parse(IP), Port);
            }        public Boolean StartSending(Byte[] sendBuff)
            {
                try
                {
                    Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);                clientSocket.BeginConnect(remoteEP, new AsyncCallback(ConnectCallBack), clientSocket);
                    connectDone.WaitOne();                Send(clientSocket, sendBuff);
                    sendDone.WaitOne();                Receive(clientSocket);
                    receiveDone.WaitOne();                clientSocket.Shutdown(SocketShutdown.Both);
                    clientSocket.Close();
                    return true;
                }
                catch (Exception e)
                {
                    e.SaveErrorLogToFile(logFileName);
                    return false;
                }
            }        private void ConnectCallBack(IAsyncResult ar)
            {            try
                {
                    Socket clientSocket = (Socket)ar.AsyncState;                clientSocket.EndConnect(ar);
                    connectDone.Set();
                }
                catch (Exception e)
                {
                    e.SaveErrorLogToFile(logFileName);
                }
            }        private void Receive(Socket clientSocket)
            {
                try
                {
                    StateObject state = new StateObject();                state.WorkSocket = clientSocket;
                    clientSocket.BeginReceive(state.Buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(RecevieCallback), state);
                }
                catch (Exception e)
                {
                    e.SaveErrorLogToFile(logFileName);
                }
            }        private void RecevieCallback(IAsyncResult ar)
            {
                try
                {
                    StateObject state = (StateObject)ar.AsyncState;
                    Socket clientSocket = state.WorkSocket;                Int32 bytesRead = clientSocket.EndReceive(ar);//无法访问已释放的对象。对象名:“System.Net.Sockets.Socket”。                if (bytesRead > 0)
                    {
                        state.StrBuilder.Append(Encoding.ASCII.GetString(state.Buffer, 0, bytesRead));
                        clientSocket.BeginReceive(state.Buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(RecevieCallback), state);
                    }
                    else
                    {
                        if (state.StrBuilder.Length > 1)
                            response = state.StrBuilder.ToString();
                        receiveDone.Set();
                    }
                }
                catch (Exception e)
                {
                    e.SaveErrorLogToFile(logFileName);
                }
            }        private void Send(Socket clientSocket, Byte[] sendBuff)
            {
                clientSocket.BeginSend(sendBuff, 0, sendBuff.Length, 0, new AsyncCallback(SendCallback), clientSocket);//由于套接字没有连接并且(当使用一个 sendto 调用发送数据报套接字时)没有提供地址,发送或接收数据的请求没有被接受。
            }        private void SendCallback(IAsyncResult ar)
            {
                try
                {
                    Socket clientSocket = (Socket)ar.AsyncState;                Int32 bytesSent = clientSocket.EndSend(ar);
                    sendDone.Set();
                }
                catch (Exception e)
                {
                    e.SaveErrorLogToFile(logFileName);
                }
            }
        }
    }出错的信息写在了相关代码的后面,现在的情况是,第一次发送是毫无问题的,问题出现在第二次发送数据的时候,而且,有时是“无法访问已释放的对象。对象名:“System.Net.Sockets.Socket”。”,有时则是“由于套接字没有连接并且(当使用一个 sendto 调用发送数据报套接字时)没有提供地址,发送或接收数据的请求没有被接受。”。
      

  3.   

    你如果要这样做的话还不如用同步Socket来实现。
      

  4.   

    在执行 到那个异常语句之前的时候,连接已经释放了,socket对象不存在了。
    推荐用网上的EMTASS,实现的不错,一般的异常都已经解决了,csdn中就有下载
      

  5.   

    在执行 到那个异常语句之前的时候,连接已经释放了,socket对象不存在了。 
    ====================================怎么样在连接释放后退出RecevieCallback呢?
      

  6.   

    连接释放后还是有点问题,就是没有真正断开连接,发送信息还是可以接收和发送.
    也就是说SendCallback/RecevieCallback未真正释放.不知哪位高手能给我们这些新手指点一二
      

  7.   

    在readcallback接收完数据之后应该请求下一次通信 就是处于等待接收状态
      

  8.   

    在readcallback接收完数据之后应该请求下一次通信吧,不然顺序工作,第一接收完处理好数据之后socket应该被释放了吧,第二次肯定不能用了啊。如果想连续首发数据貌似应该用一个循环将中间的BeginConnect到BeignRecive之间都放在循环体内吧
      

  9.   

    有Socket的代码没 我现在学这个 想研究下   谢谢
     [email protected]