socket.BeginReceive(responseBuffer,0,256,SocketFlags.None,new AsyncCallback(ReceiveCallback), udpClient);static private  void ReceiveCallback(IAsyncResult ar){}
————————————————————————————————
运行socket.BeginReceiveFrom异步接收信息时,在回调函数中设置断点发现回调函数无法正常进入,当然也就接收不到任何信息,感觉非常奇怪,是在找不到愿意同样做的发送异步socket.BeginSendTo(sendToBuffer,0,sendCommand.Length,SocketFlags.None,ipEndPoint,new AsyncCallback(SendToCallback),udpClient);
static private  void SendToCallback(IAsyncResult ar){}
却可以正常运行顺便说一句,方法全部采用static方法,socket也是静态的
是我对委托理解还不够呢?还是其他什么愿意造成的?
比较紧急,希望大家能帮忙,如果能解决,分不够可以再加呵呵 感觉这两天我把一年多积累的分全散除去了,没办法,突然被调去做以前没接触过的网络编程,还要求那么急,只好求助大家了,水平比较菜,希望回答的时候能稍微详细些,非常感谢

解决方案 »

  1.   

    汗,代码复制错了,更改如下:
    public static void BeginReceiveUdp()
    {
    IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Any,4000);
    EndPoint endPoint = (EndPoint)ipEndPoint;
    udpClient.BeginReceiveFrom(responseBuffer,0,responseBuffer.Length,SocketFlags.None,ref endPoint,new AsyncCallback(ReceiveCallback),udpClient);
    }
    static private  void ReceiveCallback(IAsyncResult ar){}
      

  2.   

    楼主给分好多, 我给你现写了一个。你试试,为了方便,也都是静态的,没有封装,测试的时候,就不断的在udpclient输入要发送的信息、回车就行,你可以多运行几个udpclient试下 :)
    udpserver.cs
    ======================
    using System;
    using System.Net;
    using System.Net.Sockets;
    public class UdpServer
    {
    static Socket serverSock;
    static AsyncCallback receiveCallback;
    static byte[] buff;
    static EndPoint senderIP ; public static void Main()
    {
    buff = new byte[1024];
    senderIP = new IPEndPoint(IPAddress.Any, 0); receiveCallback = new AsyncCallback(OnDataReceived); serverSock = new Socket(AddressFamily.InterNetwork,
    SocketType.Dgram, ProtocolType.Udp);
    serverSock.Bind(new IPEndPoint(IPAddress.Any, 8000));
    serverSock.BeginReceiveFrom(buff, 0, buff.Length, SocketFlags.None,
    ref senderIP, receiveCallback, serverSock); Console.ReadLine();

    } public static void OnDataReceived(IAsyncResult ar)
    {
    Socket udpSocket = ar.AsyncState as Socket;
    int bytesRecved = udpSocket.EndReceiveFrom(ar, ref (EndPoint)senderIP);

    Console.WriteLine("{0}传来消息{1}", senderIP.ToString(), System.Text.Encoding.ASCII.GetString(buff, 0, bytesRecved)); serverSock.BeginReceiveFrom(buff, 0, buff.Length, SocketFlags.None,
    ref senderIP, receiveCallback, serverSock);
    }
    }udpclient.cs
    ==============================================
    using System;
    using System.Net;
    using System.Net.Sockets;
    public class UdpClient
    {
    static Socket clientSock;
    static byte[] buff;

    public static void Main()
    {
    clientSock = new Socket(AddressFamily.InterNetwork,
    SocketType.Dgram, ProtocolType.Udp); string input;
    while((input = Console.ReadLine()) != "exit")
    {
    buff = System.Text.Encoding.ASCII.GetBytes(input);
    clientSock.SendTo(buff, 0, buff.Length, SocketFlags.None, new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8000));
    } clientSock.Close();
    }
    }
      

  3.   

    查了一下,发现是BeginReceiveFrom没有生成新的线程,但不知道如何解决再说明下,上面udpClient.BeginReceiveFrom()中的udpClient不是UdpClient类,而是我生成的一个socket对象,静态的
      

  4.   

    send端,我没有写成异步的, 因为你说SendTo没有问题,呵呵,基本原理套路都是一样地
    服务器端代码我没写 serverSock.Close,呵呵,你自己加上
      

  5.   

    异步的比较麻烦, 只要调用了BeginReceiveFrom就会在新的线程上收取数据,
    楼主是不是忘了在回雕函数里 调用 EndReceiveFrom,不调的话,数据是不会反回来地
      

  6.   

    Moon1(静静的黎明) 
    我关键是用BeginReceiveFrom的时候不知道为什么程序进不去回调函数,用断点查了没有,也没有生成相应的线程呵呵 我研究下你的代码,先在这里谢谢了
      

  7.   

    没有啊,而且就算有防火墙,BeginReceiveFrom也应该可以创建新的线程,只不过收不到数据而已吧?
      

  8.   

    还是那句话,楼主依然用异步的,就仔细检查下代码。
    udp异步的,内部应该是封装的win32 的select模型吧,其实一般场合下,我觉得udp,用组塞的模型已经够用,毕竟udp很快的,而且适合发那种小量的数据
      

  9.   

    Moon1(静静的黎明) 
    这个。我用你的代码调试了,在BeginReceiveFrom的时候也是没有进入回调函数,也没有创建新的线程
    udpserver.cs程序运行完BeginReceiveFrom就这么结束了,按道理应该进入回调函数并一直循环下去的啊汗,难道是我的.NET有问题?虽然不是正版,但也不至于如此吧........
      

  10.   

    BeginReceiveFrom后面的Console.ReadLine你写了么???这里必须卡住主线程
    否则的话,主线程就退出了,整个程序也退出来了
      

  11.   

    还有,如果你建项目的话,要用命令控制台项目我是直接用csc编译的
      

  12.   

    Console.ReadLine写了
    我是用断点单步调试的,运行完BeginReceiveFrom的时候(也就是开始运行Console.ReadLine的时候),应该会新建一个线程跑回调函数的,但回调函数中的断点没有反映,查看线程也没有见到新建线程
    这种情况下就算主线程卡住不退出也是一样的啊
      

  13.   

    回调函数不会马上被调用,只有受到client的信息之后,回调函数才会被调用。 这个时候,缓冲区里也才有数据。你测试下,udpclient发数据之后,server 的回调被调用没
      

  14.   

    运行了以后提示异常:通常每个套接字地址(协议/网络地址/端口)只允许使用一次我把udpserver.cs和udpclient.cs中的端口制定为不同端口就没这个问题了,请问这个是什么意思?
    不大理解,在udpclient.cs中的8000端口应该是目标主机端口,发送端口为系统自动分配的(我通过抓包查看过了,发送端口是2781)
    udpserver.cs中的8000端口应该是SOCKET的绑定端口吧?也就是说发送和监听都用这个端口好像没有什么矛盾啊
      

  15.   

    恩,的确是只有受到client的信息之后,回调函数才会被调用。解决了我一大理解障碍,非常感谢汗,“通常每个套接字地址(协议/网络地址/端口)只允许使用一次”也搞明白了,我把抓包工具打开监听8000端口的时候,它占用了8000端口,所以再创建udpserver的时候就提示SOCKET已经被占用请问有什么办法判断某端口是否被占用?马上再去调试我的代码,呵呵,解决了马上给分
    实在是太感谢了!!!
      

  16.   

    你说的没错。可能是有其他程序也占用了8000,或者你无意运行了两个server,用任务管理器看下。给你的程序,我在我本机上,开一个server, 两个client(client自动分配断口),同时运行是没有问题的。
      

  17.   

    一般处理端口被占用的问题上。
    server没什么商量的,流程就是:如果你选定的端口被站用, Bind抛异常。程序初始化错误,退出当然你可以在这里换一个端口,重新bind,一般没这个必要;
      

  18.   

    T_T是在太感谢了,原来是回调函数不会马上被调用,只有受到client的信息之后,回调函数才会被调用。
    我原来的代码是正确的,只是客户机器没有正确响应,但由于是异步接收不如同步直观我看到BeginReceiveFrom没有直接进入回调函数就还以为我的代码有问题结果把一个晚上加一个上午搭进去了=.=b真够要命;对SOCKET理解还不够深入啊看来顺便再问一个问题,按我的理解,异步其实就是新开一个线程,在新线程中同步发送和监听,以免阻塞主线程,那就有问题了,BeginReceiveFrom的回调函数也可以说新线程没有马上建立,也就是说BeginReceiveFrom并不会马上去监听端口取数据,那它怎么知道消息来了?莫非是当有数据进入SOCKET缓冲区的时候,会再引发一个事件通知BeginReceiveFrom去调用其回调函数,然后回调函数中的EndReceiveFrom实际并不会像Receive一样阻塞等待接收数据,而是阻塞读取数据的方法而已
    ——————————————————————————————————————
    可以这么理解吗?靠,被Receive方法误导了,我还以为是新开了一个线程,然后EndReceiveFrom就像Receive一样阻塞住此线程,等待数据接收。。没想到EndReceiveFrom阻塞只是负责读取缓冲区数据的(也就是说数据事先已到);万恶的MSDN,居然这么重要的东西也不说清楚点T_T 还是我的理解能力太菜了?
      

  19.   

    非常感谢 Moon1(静静的黎明) 的帮忙,帮了我的大忙了,SOCKET总算有了初步的理解了http://community.csdn.net/Expert/topic/5483/5483570.xml?temp=.7160608这个帖子也随着这个问题解决要结了,如果你不介意的话去那里也回一帖,我再结些分给你
      

  20.   

    我去接分了。你理解的差不多。
    异步版的BeginReceive,你可以这么理解,就是另起一个线程的Receive(实际要复杂多),在那个线程中等待,当那个线程有数据到来时,他会调用你定义的回雕函数, 你在回调函数里EndReceive,就把数据拷贝过来了,并结束一个Receive。其实EndReceive会组塞线程,不过在回调函数中,数据已经到了了,所以不会组塞住了。这是微软的封装模型,咱们基本上得按这个模型的套路走, 不过效率没得说,他内部实现估计应该是用的线程池,效率比咱们自己简单的起线程要高得多MSDN上关于Socket都是简单的例子,或者是程序片段,看起来确实有点摸不到边,找些大工程来看。
      

  21.   


    【中国软件开发联盟】www.itebase.com 欢迎你的加入!提供.NET,ASP.NET,C#,VB.NET,JAVA,C++,DELPHI,PHP,MS SQL,MySql,ORACLE,UML建模,软件工程...等技术的学习交流和经验,资料,源码共享...http://www.itebase.com