private void SendCallback(IAsyncResult ar)
        {   // 从state对象中获取socket  
            Socket client = (Socket)ar.AsyncState;   // 完成数据发送.  
            int bytesSent = client.EndSend(ar);
        }        private static void ReceiveCallback(IAsyncResult ar)
        {   // 从输入参数异步state对象中获取state和socket对象              StateObject state = (StateObject)ar.AsyncState;
            Socket client = state.workSocket;   //从远程设备读取消息头 
            int bytesRead = client.EndReceive(ar);            if (bytesRead > 0)
            {  // 有数据,存储.                  string headstr = Encoding.Default.GetString(state.buffer, 0, bytesRead);                state.sb.Append(headstr);   // 继续读取.                                     client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
            }
            else
            {  // 所有数据读取完毕.  
                if (state.sb.Length > 1) { response = state.sb.ToString(); }  // 所有数据读取完毕的指示信号.  
                receiveDone.Set();
            }        }

解决方案 »

  1.   

    异步socket时send数据包后EndReceive不执行,高手帮帮忙!但用截包工具可以看到数据包已成功返回!
      

  2.   

    实际上,也不知道怎么回事,msdn中的异步通讯代码是我在msdn上见过最烂的代码。msdn中的代码使用了一个同步信号量,既用异步代码来模拟同步控制流程。你可以看到msdn的所谓异步编程范例程序的主线程上是使用一个循环来控制的,这样做,你的程序没有真正用到异步编程的好处。实际上在异步编程代码中,主线程也根本不需要任何循环语句,而处理接收信息的代码最后也根本不需要 receiveDone.Set() 这类。
      

  3.   

    你的代码不全,看不出第一个调用 client.BeginReceive 的代码。你是想在Send之后Receive?那么在SendCallback最后一句调用 BeginReceive 啊!
      

  4.   

    你凭什么说EndReceive不执行,你有断点调试过吗?
    只要进入ReceiveCallback回调函数,“int bytesRead = client.EndReceive(ar); ”这句肯定会被执行,除非未收到数据。
      

  5.   

    短连接的客户端程序流程大致应这样:
    主线程: 1. 开始异步connect,连接指定host、指定端口。
    connect回调方法:
     1. End异步Connect。
     2. 开始异步Send,一次性发送完整的数据包。Send回调方法:
     1. End异步Send。
     2. 开始异步Receive。Receive回调方法:
     1. End异步Receive。
     2. 保存缓冲区中的数据。
     3. 判断是否消息结束:
        3.1 如果结束,关闭连接,返回累计接收到数据,退出。
        3.2 如果没有结束,开始异步Receive。
    服务端的程序,则顺序相反,它是异步Accept,然后异步Receive,(递归调用异步Receive直到接收结束)然后异步Send。
      

  6.   

    看不到你的第一个BeginReceive 写在那里,不知道接收过程是如何启动的。
      

  7.   

    sorry,“3.1 如果结束,关闭连接,返回累计接收到数据,退出。”这句话可能有点误导。实际我是想写:3.1 如果结束,关闭连接,使用累计接收到数据通知给使用者(事件或者delegate),退出。也就是说,并不是receiveDone.Set(),而是在线程中回调使用者,传递接收到的数据给调用者的回调程序来干一件事(例如在GUI上显示)。这是异步处理过程。而receiveDone.Set我从你的代码上猜测你是在一开始搞了同步信号量控制,这种用异步代码来模拟同步控制的做法我觉得要不得。
      

  8.   


    没有进到ReceiveCallback函数,就像建立连接一样,不进行接收处理,不知为什么
      

  9.   


                        Send(client, sendtxt);
                        sendDone.WaitOne();                    Receive(client);
                        receiveDone.WaitOne();
            private void Send(Socket client, String data)
            {  // 格式转换.  
                data= data.Replace(" ","");
                int len = data.Length;
                byte[] byteData = new byte[len/2];
                int j = 0;
                for (int i = 0; i < len; i=i+2)
                {
                    byteData[j] = (byte)Convert.ToInt32(data.Substring(i,2), 16);
                    j++;
                }
                //byte[] byteData = Encoding.ASCII.GetBytes(data + "\r\n\r\n");   // 开始发送数据到远程设备.              //writetoX(byteData);
                client.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), client);
            }
      

  10.   

    SendCallback里面有sendDone.Set()        private void SendCallback(IAsyncResult ar)
            {   // 从state对象中获取socket  
                Socket client = (Socket)ar.AsyncState;   // 完成数据发送.  
                int bytesSent = client.EndSend(ar);
                
          
                // SetText("Sent " + bytesSent + " bytes to server." + "\r\n");   // 指示数据已经发送完成,主线程继续.  
                sendDone.Set();
            }
      

  11.   

    在SendCallback函数中没有sendDone.Set()的调用啊,你发送完了要设置sendDone, 不让程序会在sendDone.WaitOne(); 处等待sendDone.Set()的调用,你Receive(client)根本就不会执行,有怎么会执行 ReceiveCallback()啊。
      

  12.   

    http协议的可以接受,但TCP的好像根本不会接受,发送完数据就直接返回数据,好像是socket自己接收的,不用我另外再接受;就是建立连接一样,发送连接请求,返回连接成功数据,不用EndReceive;有什么例子提供我参考下吗?谢谢!
      

  13.   


    有sendDone.Set()的,调试这个已经执行
      

  14.   

    if (bytesRead > 0) 
    这个不是数据接收完的判断是该 连接是否断开的判断
      

  15.   


    using System;
    using System.Text;
    using System.Windows.Forms;
    using System.Net.Sockets;
    using System.Net;
    using System.Threading;
    using System.Globalization;
    using System.IO;namespace test2
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }        // ManualResetEvent instances signal completion. 
            private static ManualResetEvent connectDone;
            private static ManualResetEvent sendDone;
            private static ManualResetEvent receiveDone;
            // The response from the remote device. 
            private static String response = String.Empty;        bool isESTA = false; Socket myclient;//是否保持连接
        
            private void btnSend_Click(object sender, EventArgs e)
            {
                isESTA = checkBox1.Checked;//是否保持连接
                connectDone = new ManualResetEvent(false);
                sendDone = new ManualResetEvent(false);
                receiveDone = new ManualResetEvent(false);            StartClient(txtSendContent.Text.Trim(), isESTA);        }        private void button1_Click(object sender, EventArgs e)
            {   //清空返回数据
                richTextBox1.Clear();
            }
            private void button2_Click(object sender, EventArgs e)
            {   //断开连接
                if (myclient != null)
                {
                    myclient.Shutdown(SocketShutdown.Both);
                    myclient.Close();
                    myclient = null;
                }
            }
            /// <summary>
            /// 发送包头数据
            /// </summary>
            /// <param name="sendtxt">包头数据</param>
            /// <param name="keepalive">是否保持连接</param>
            private void StartClient(string sendtxt, bool keepalive)
            {
                try
                {
                    Socket client = myclient;                IPAddress ipAddress = IPAddress.Parse(txtHostIP.Text.Trim());
                    IPEndPoint remoteEP = new IPEndPoint(ipAddress, Convert.ToInt32(txtPort.Text.Trim()));                if (client == null)
                    {
                        client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                        client.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback), client);
                        connectDone.WaitOne();
                    }
                    //if (sendtxt != "")
                    //{
                    Send(client, sendtxt);
                    sendDone.WaitOne();
                    if (checkBox2.Checked)
                    {
                        Receive(client, comboBox1.Text, txtEnCode.Text.Trim());
                        receiveDone.WaitOne();
                    }
                    //  }
                    SetText("Response received :\r\n" + response + "\r\n");
                    if (!keepalive)
                    {
                        client.Shutdown(SocketShutdown.Both);
                        client.Close();
                        myclient = null;
                    }
                    else
                    {
                        myclient = client;
                    }
                }
                catch (Exception e)
                {
                    SetText(e.ToString() + "\r\n");
                }        }        delegate void SetTextCallback(string text);
            private void SetText(string text)
            {
                if (this.richTextBox1.InvokeRequired)
                {
                    SetTextCallback d = new SetTextCallback(SetText);
                    this.Invoke(d, new object[] { text });
                }
                else
                {
                    richTextBox1.AppendText(text);
                }
            }        public string HexToStr(string mHex) // 返回十六进制代表的字符串 
            {
                mHex = mHex.Replace(" ", "");
                if (mHex.Length <= 0) return "";
                byte[] vBytes = new byte[mHex.Length / 2];
                for (int i = 0; i < mHex.Length; i += 2)
                    if (!byte.TryParse(mHex.Substring(i, 2), NumberStyles.HexNumber, null, out vBytes[i / 2]))
                        vBytes[i / 2] = 0;
                return ASCIIEncoding.Default.GetString(vBytes);
            }        public class StateObject
            {
                // Client socket. 
                public Socket workSocket = null;
                // Size of receive buffer. 
                public const int BufferSize = 1024;
                // Receive buffer. 
                public byte[] buffer = new byte[BufferSize];
                // Received data string. 
                public StringBuilder sb = new StringBuilder();
            }        private void ConnectCallback(IAsyncResult ar)
            {   // 从state对象获取socket. 
                Socket client = (Socket)ar.AsyncState;   // 完成连接.  
                client.EndConnect(ar);
                // SetText("Socket connected to " + client.RemoteEndPoint.ToString() + "\r\n");   // 连接已完成,主线程继续.  
                connectDone.Set();
            }        private static void Receive(Socket client, string xy, string bm)
            {
                if (xy == "HTTP")
                {
                    response = httppro.ReceiveData(client, bm);                receiveDone.Set();
                }
                else
                {
                    // 构造容器state.  
                    StateObject state = new StateObject();
                    state.workSocket = client;   // 从远程目标接收数据.                  client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
                }
            }        private static void getreceiveData(Socket socket)
            {
                StringBuilder header = new StringBuilder();            while (true)
                {
                    byte[] data = new byte[1];
                    //接收一个字节
                    int rece = socket.Receive(data, 1, SocketFlags.None);                //转换为char
                    char c = (char)data[0];                header.Append(c);                if (header.ToString().IndexOf("┅") > 0)
                    {
                        response = header.ToString();
                        break;
                    }
                }
            }        private static void ReceiveCallback(IAsyncResult ar)
            {   // 从输入参数异步state对象中获取state和socket对象              StateObject state = (StateObject)ar.AsyncState;
                Socket client = state.workSocket;   //从远程设备读取消息头 
                int bytesRead = client.EndReceive(ar);            if (bytesRead > 0)
                {  // 有数据,存储.                  string headstr = Encoding.Default.GetString(state.buffer, 0, bytesRead);                state.sb.Append(headstr);   // 继续读取.                     
                    if (headstr.IndexOf("b") > -1)//
                    {                    receiveDone.Set();
                        return;
                    }
                    client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
                }
                else
                {  // 所有数据读取完毕.  
                    if (state.sb.Length > 1) { response = state.sb.ToString(); }  // 所有数据读取完毕的指示信号.  
                    receiveDone.Set();
                }        }
      

  16.   


            private static void ReceiveCallback2(IAsyncResult ar)
            {
                //检索异步结构对象并且处理从异步结构对象过来的套接字 
                StateObject state = (StateObject)ar.AsyncState;
                Socket handler = state.workSocket;            //Socket handler = state.workSocket; 
                //EndReceive 方法完成在 BeginReceive 方法中启动的异步读取操作。返回值接收到的字节数。 
                int bytesRead = 0;
                try
                {
                    if (handler != null && handler.Connected)
                    {
                        bytesRead = handler.EndReceive(ar);//从客户端套接字读取数据 
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show("读取错误:" + ex.Message.ToString());
                }            if (bytesRead == 0)
                {
                    receiveDone.Set();
                }            if (bytesRead > 0)//可能会有更多的数据,因此存储迄今为止收到的数据。 
                {
                    state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));
                    //检查文件结束标志,如果不是结束,则继续读取更多的数据 
                    response = state.sb.ToString();
                    if (response.IndexOf("EOF") > -1)
                    {//所有数据都已经读取完毕,则处理                     receiveDone.Set();
                    }
                    else
                    {//还有数据需要读取,继续读数据 
                        handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback2), state);
                    }
                }        }
            private void Send(Socket client, String data)
            { 
                // 格式转换.  
                data = data.Replace(" ", "");
                int len = data.Length;
                byte[] byteData = new byte[len / 2];
                int j = 0;
                for (int i = 0; i < len; i = i + 2)
                {
                    byteData[j] = (byte)Convert.ToInt32(data.Substring(i, 2), 16);
                    j++;
                }            // 开始发送数据到远程设备.  
                client.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), client);
            }        private void SendCallback(IAsyncResult ar)
            {   // 从state对象中获取socket  
                Socket client = (Socket)ar.AsyncState;   // 完成数据发送.  
                int bytesSent = client.EndSend(ar);
                // SetText("Sent " + bytesSent + " bytes to server." + "\r\n");   // 指示数据已经发送完成,主线程继续.  
                sendDone.Set();
            }        void writetoX(byte[] bt)
            {
                string aa = "";            for (int i = 0; i < bt.Length; i++)
                {
                    if (bt[i].ToString() == "0")
                    {
                        aa += "  ";
                        continue;
                    }
                    if (bt[i].ToString("X").Length != 1)
                    {
                        aa += bt[i].ToString("X");
                    }
                    else
                    {
                        aa += "0" + bt[i].ToString("X");
                    }            }            StreamWriter sw = File.AppendText("c:\\test2.txt");
                sw.WriteLine(DateTime.Now);
                sw.WriteLine(aa);
                sw.WriteLine(HexToStr(aa));
                sw.Flush();
                sw.Close();        }    }
    }
      

  17.   


    设了断点,ReceiveCallback都没进去
      

  18.   

    Receive和ReceiveCallback方法之前的static 去掉