通常的服务器程序都调用一个函数listen(),你怎么没有调用?listen(sock_udp,5);
wsaeventselect(....);

解决方案 »

  1.   

    to  BCB_FANS(四大名捕之追杀令)
    udp数据报不需要listen吧?
      

  2.   

    to  BCB_FANS(四大名捕之追杀令)
    udp数据报不需要listen吧?
      

  3.   

    哦,说错了,不好意思.不过既然wsaasyncselect模型就没问题,为什么不用它呢?
      

  4.   

    wsaasyncselect接收到的udp包,遗漏较多(发送方瞬间发送大量,从网络连接的状态那里可以看到数据报送过来了,可是程序里却遗漏较多,原因不详)。我想试一试wsaeventselect模型,看看效果如何。
      

  5.   

    我把你的代码重新用BCB写,再编译运行,一切正常,我实在也想不出哪里有问题.-----------------------------------------
      sockaddr_in SockAddr;
      SOCKET ListenSocket;
      HANDLE hEvent;
      WSADATA Data;  ZeroMemory(&SockAddr,sizeof(sockaddr_in));  SockAddr.sin_family=AF_INET;
      SockAddr.sin_addr.s_addr=inet_addr("218.65.236.76");//这是我的动态IP地址,不是局域网地址
      SockAddr.sin_port=5252;
      if(WSAStartup(MAKEWORD(2,0),&Data)!=0)
      {
        Memo1->Lines->Add("Error Call WSAStartup");
        return;
      }  ListenSocket=socket(AF_INET,SOCK_DGRAM,0);
      if(ListenSocket==INVALID_SOCKET)
      {
        Memo1->Lines->Add("Error Create Socket="+SysErrorMessage(WSAGetLastError()));
        return;
      }  hEvent=CreateEvent(NULL,false,false,NULL);
      if(hEvent==NULL)
      {
        Memo1->Lines->Add("Error Create Event="+SysErrorMessage(GetLastError()));
        return;
      }
      if(bind(ListenSocket,(const struct sockaddr FAR*)&SockAddr,sizeof(sockaddr_in))==SOCKET_ERROR)
      {
        Memo1->Lines->Add("Error Bind Socket="+SysErrorMessage(WSAGetLastError()));
        return;
      }  WSAEventSelect(ListenSocket,hEvent,FD_READ);//一切正常
      

  6.   

    还有,你应该检查一下bind函数的返回值,说不定这一步就已经失败了,才引起后面的失败.
      

  7.   

    BCB_FANS(四大名捕之追杀令) 谢谢你
    我也不清楚问题出在哪里,bind函数没错的,我用wsaasyncselect模型在这套接字上可以接收。而且,如果不用createevent而是用wsacreateevent的话,在执行wsacreateevent这一句时也出现同样错误。我想是不是引用SConnect单元的问题??
      

  8.   

    我引用的是WinSock2.h中的函数,Lib为WS2_32.lib,怎么没有听说过SConnect单元?
      

  9.   

    你那有delphi吗?麻烦试试,我分别在两台机子上试过,结果都一样,是不是因为delphi对api函数的支持不够,还是我装的盗版有问题?我用opendriver(pwidechar(pchar('system.ini中指定的字符串')),nil,0);
    无法打开指定的设备驱动?
    同一台机子,
    DELPHI:
    hdrv:=opendriver(pwidechar(pchar('VIDC.IV32')),nil,0);//返回0;
    VC:
    hdrv=(HDRVR)OpenDriver(L"VIDC.IV32",NULL,0L);//返回非0;
    究竟是什么回事,谁能帮我解说一下?????
      

  10.   

    你那有delphi吗?麻烦试试,我分别在两台机子上试过,结果都一样,是不是因为delphi对api函数的支持不够,还是我装的盗版有问题?我用opendriver(pwidechar(pchar('system.ini中指定的字符串')),nil,0);
    无法打开指定的设备驱动?
    同一台机子,
    DELPHI:
    hdrv:=opendriver(pwidechar(pchar('VIDC.IV32')),nil,0);//返回0;
    VC:
    hdrv=(HDRVR)OpenDriver(L"VIDC.IV32",NULL,0L);//返回非0;
    究竟是什么回事,谁能帮我解说一下?????
      

  11.   

    我对Delphi不是很熟,所以没有装,连盘都没有.
      

  12.   

    下午我去找一下Delphi盘回来装,再帮你试一下,请等待......
      

  13.   

    >>if (WSAStartup(makeword(2,2),wsadata)<>0) then
    ..>> >>if(WSAStartup(MAKEWORD(2,0),&Data)!=0)
                    ~~~~~~~~~~\看看是不是跟你系统的Socket版本有关?
      

  14.   

    to  halfdream(哈欠)
    没用,还是同样出错。
      

  15.   

    >>event1:=createevent(nil,false,false,nil);怀疑是事件创建不成功。event1的值为空,则后面出现access violation at address 我以前遇到过,
    有时CreateEvenT的第四个参数为NULL的时候,创建事件不成功。
    试试把创建的事件指定个名字。
    比如改成
    event1:=createevent(nil,false,false,'udp_event');希望有用。
      

  16.   

    >>如果不用createevent而是用wsacreateevent的话,在执行wsacreateevent这>>一句时也出现同样错误。关于这个问题是这样:
    在Sconnect单元里面是动态载入 winsock2的,你必须调用它的
    function LoadWinSock2: Boolean;后才可以使用WSACreateEvent
    你看看Sconnect单元的相关源码就会知道的。
      

  17.   

    >>如果不用createevent而是用wsacreateevent的话,在执行wsacreateevent这>>一句时也出现同样错误。关于这个问题是这样:
    在Sconnect单元里面是动态载入 winsock2的,你必须调用它的
    function LoadWinSock2: Boolean;后才可以使用WSACreateEvent
    你看看Sconnect单元的相关源码就会知道的。
      

  18.   

    谢谢你halfdream(哈欠) ,可以使用了。有个新问题再问你一下。
        createevent(nil,false,false,nil);
        wsaeventselect(sock_udp,event1,fd_read);    
        thread1:=createthread(nil,0,@threadread,nil,0,threadid1);接收线程
    var
      p:^recvdata;
        waitforsingleobject(event1,infinite);
        getmem(p,sizeof(recvdata));
        zeromemory(p,sizeof(recvdata));
        count:=recvfrom(sock_udp,p^,sizeof(recvdata),0,addr_r,i);
    返回错误:10014 地址错误;
    可是在wsaasyncselect模型下,同样的语句可以接收到数据。
    可以解释一下是什么原因吗?
      

  19.   

    哦,是在recvfrom时返回的错误。
    var
      Form1: TForm1;
      sock_udp:integer;
      

  20.   

    还有,第一次接收出错以后,第二次来数据时没有重置event1为有信号。
    waitforsingleobject(event1,infinite);一直等待。
    procedure threadread;
    var
    p:recvpoin;
    addr_r:sockaddr_in;
    count,i,sock:integer ;
    begin
        while (true) do
        begin
           waitforsingleobject(event1,infinite);
           getmem(p,sizeof(recvdata));
           zeromemory(p,sizeof(recvdata));
           //sock_udp 是在form1.create中创建并跟fd_read捆绑一起的udp套接字
           count:=recvfrom(sock_udp,p^,sizeof(recvdata),0,addr_r,i);
           if count=socket_error then
           begin
     ndmessage(form1.ListBox1.Handle,lb_addstring,0,longint(inttostr(wsagetlasterror())));//报错10014:地址出错;
           end;
           freemem(p);
           resetevent(event1);
        end;
    end;