我把socket操作写成了一个类ctrl,然后我想在程序调用时ctrl c = new ctrl(); c.openClient();来打开连接,然后调用
c.send(); 进行数据发送,请问这样为何不行?
class ctrl
    {
        #region socket操作
        private int port = 2000;
        // ManualResetEvent instances signal completion.
        private ManualResetEvent connectDone =
            new ManualResetEvent(false);
        private ManualResetEvent sendDone =
            new ManualResetEvent(false);
        private ManualResetEvent receiveDone =
            new ManualResetEvent(false);
        Socket client;        // The response from the remote device.
        private static String response = String.Empty;        public bool openClient()
        {
            try
            {
                IPHostEntry ipHostInfo = Dns.Resolve("localhost");
                IPAddress ipAddress = ipHostInfo.AddressList[0];
                IPEndPoint remoteEP = new IPEndPoint(ipAddress, port);                // Create a TCP/IP socket.
                client = new Socket(AddressFamily.InterNetwork,
                    SocketType.Stream, ProtocolType.Tcp);                // Connect to the remote endpoint.
                client.BeginConnect(remoteEP,
                    new AsyncCallback(ConnectCallback), client);
                connectDone.WaitOne();                return true;            }
            catch (Exception e)
            {                GlobalApp.loger.Error("openClient", e);
                return false;
            }
        }        private void closeClient()
        {
            if (client.Connected)
            {
                // Release the socket.
                client.Shutdown(SocketShutdown.Both);
                client.Close();
            }
        }        private void ConnectCallback(IAsyncResult ar)
        {
            try
            {
                // Complete the connection.
                client.EndConnect(ar);                // Signal that the connection has been made.
                connectDone.Set();                Receive(client);
            }
            catch (Exception e)
            {
                connectDone.Set();
                GlobalApp.loger.Error("ConnectCallback", e);
            }
        }        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 e)
            {
                GlobalApp.loger.Error("Receive", e);
            }
        }        private void ReceiveCallback(IAsyncResult ar)
        { }
        public void Send(String data)
        {
            // Convert the string data to byte data using ASCII encoding.
            byte[] byteData = Encoding.ASCII.GetBytes(data);            this.client.BeginSend(byteData, 0, byteData.Length, 0,
                new AsyncCallback(SendCallback), this.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);                // Signal that all bytes have been sent.
                sendDone.Set();
            }
            catch (Exception ex)
            {
                GlobalApp.loger.Error("SendCallback失败", ex);
                sendDone.Set();            }
        }        #endregion
    }

解决方案 »

  1.   

    代码好长,没有看明白你到底问什么问题(你应该先debug调试,然后直接说明问题)。
      

  2.   


    调用的代码:
    private void btnSet_Click(object sender, EventArgs e)
            {
    ctrl c = new ctrl();
                if (c.openClient())
                {
                    MessageBox.Show("success");
                    c.Send("aaa");
                }
                else
                    MessageBox.Show("fail");
    }出现的问题:
    由于套接字没有连接并且(当使用一个 sendto 调用发送数据报套接字时)没有提供地址,发送或接收数据的请求没有被接受。位置:
    this.client.BeginSend(byteData, 0, byteData.Length, 0,
                    new AsyncCallback(SendCallback), this.client);谢谢
      

  3.   

    也还是没有看你的代码。说实在代码好长,而你的问题不明显。不过,我看到了ManualResetEvent,以及WaitOne。这个我的感觉非常强烈,说实在的与其抄袭msdn上这个弱智的代码,你不如直接用同步处理而不是异步处理。msdn上面这个代码示例,在示例异步编程的地方,却模仿同步控制机制来控制流程(发出异步处理指令之后立刻阻塞当前线程),纯粹是画蛇添足的代码。与其这样,直接用同步处理代码,它本身就阻塞了线程,而不需要你在好几个地方使用信号控制代码。它的同步处理代码是经过考验的,你写一堆代码来在异步处理过程中模仿同步处理流程,简直是被msdn害了。
      

  4.   

    真正的异步处理代码根本不应该阻塞,根本不需要写什么   connectDone.WaitOne();和   sendDone.WaitOne();  //你好像丢了这个?以及配套的 Set 代码。根本不需要使用WaiOne阻塞,直接结束就可以了,那样才是高效而且简单得多的异步处理。
      

  5.   

    遇到过被msdn所害的读者。有人就这样跟我说:“我就是异步处理的啊,就是msdn那样写的”。唉,这个msdn只是给你演示异步处理的那条语言怎么写(怎么样编译通过),可是这个程序比同步处理还不如。阻塞当前线程,还能自认为是在异步处理消息吗?就算你的代码确实使用了异步处理的那个语句,又怎样?我看其实现的逻辑根本就不是异步的。
      

  6.   

    好像你没有listen吧?我先把你代码里面的BeginConnect改成connect 马上报错,后来发现没有监听这个端口,你连接怎么能连的上去呢?
    附段监听代码
     public void BeginListen()
            {
      IPHostEntry ipHostInfo = Dns.Resolve("localhost");
                IPAddress ipAddress = ipHostInfo.AddressList[0];
                IPEndPoint remoteEP = new IPEndPoint(ipAddress, port);            server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);            byte[] byteMessage = new byte[100];
                server.Bind(remoteEP);            // do             while (true)
                {                try
                    {                    server.Listen(5);                    Socket newSocket = server.Accept();                    newSocket.Receive(byteMessage);                    string sTime = DateTime.Now.ToShortTimeString();                    string msg = sTime + ":" + "Message from:";                    msg += newSocket.RemoteEndPoint.ToString() + Encoding.Default.GetString(byteMessage);                    // this.listBox1.Items.Add(msg); 
                    }
                    catch (Exception ex)
                    { }            }}
    然后先new个thread来开启监听,我试了好像就可以了