+++++++++++++++++ UDP的简单问题 +++++++++++++++

 所属目录:Java   |   类型:技术问答   |   时间:2007-05-21
 问题:

我用sendto   向外发一个包,这时源端口是随机的,我如何能做到recvfrom   接收从服务器发来的回应包呢???不用csocket,直接用api,请问如何实现呢???

· 网友精彩回答:

发表者:surstar

sendto   向外发一个包时要用到一个hsocket句柄   在接受服务器方发回来的数据时fd_read消息的wparam       就是接受的hsocket

发表者:masterz

看看这个例子  
  http://cs.ecs.baylor.edu/~donahoo/practical/csockets/code/udpechoclientws.c  
 

发表者:goodboyws

用raw   socket应该可以解决你的问题

发表者:oyljerry

帮顶好发送的socket   handle,然后响应fd_read消息好了

发表者:newbiestar

recvfrom在msdn里面是这么解释的……  
   
  the   recvfrom   function   receives   a   datagram   and   stores   the   source   address.  
   
  int   recvfrom(  
      socket   s,  
      char*   buf,  
      int   len,  
      int   flags,  
      struct   sockaddr*   from,  
      int*   fromlen  
  );  
   
  s    
  [in]   descriptor   identifying   a   bound   socket.    
   
  看到这个了吧?s是一个被绑定的socket……这样的话你才能接受数据……  
   
  也就是说,你要先调用bind,把这个socket和一个固定的端口绑定才行……

发表者:newbiestar

没办法,无连接的东西就是这个不好……

发表者:softrain

只要sendto过,就不需要bind了,因为sendto时系统已经为它分配了一个端口号了。只要用这个socket   recvfrom即可。

发表者:orbit

udp不需要绑定,使用sendto的那个socket句柄recvfrom就行了  
   
  recvfrom是个堵塞函数,如果使用fd_read事件需要使用winsocket的异步消息函数

发表者:surstar

汇编写的要么?   看不懂的汇编代码我可以给你讲,要就加我msn:yuhejun@uisoft.net  
   
  客户端:  
  .386  
  .model   flat,   stdcall  
  option   casemap:none  
   
  include windows.inc  
  include user32.inc  
  includelib user32.lib  
  include kernel32.inc  
  includelib kernel32.lib  
  include wsock32.inc  
  includelib wsock32.lib  
   
  ;equ  
  ico_main   equ   1000  
  dlg_main   equ   2000  
  idc_server   equ   2001  
  idc_port   equ   2002  
  idc_status   equ   2003  
  idc_close   equ   2004  
  wm_udp   equ   wm_user   +   100  
  .data  
  szip   db   192.168.17.123,   0  
  dwreturn1   dd   -   1  
  dwreturn2   dd   -   2  
  szerrorip   db   ip地址出错了!,   0  
  szerrorport1   db   port填写错误,必须为非负数,   0  
  szerrorport2   db   获取端口失败!,   0  
  sztip1   db   已经向服务器发出了数据,   0  
  ;use   to   debug  
  ;szdebugformat   db   %d,   0  
  ;szdebugbuffer   db   1024   dup(?)  
  .data?  
  hwinmain   dd   ?  
  hsocket   dd   ?  
  uport   dd   ?  
  szreadbuffer   db   1024   dup(?)  
  .code  
  _init   proc  
  local   @stwsa:wsadata  
   
  invoke   setdlgitemtext,   hwinmain,   idc_server,   addr   szip  
  invoke   wsastartup,   101h,   addr   @stwsa  
  invoke   socket,   af_inet,   sock_dgram,   0  
  mov   hsocket,   eax  
  invoke   wsaasyncselect,   hsocket,   hwinmain,   wm_udp,   fd_read   or   fd_write  
  ret  
  _init   endp  
   
  _recvdata   proc   _hsocket  
  local   @dwrecv,   @dwsize  
  local   @stsin:sockaddr_in  
   
  mov @dwsize,sizeof   @stsin  
  invoke rtlzeromemory,addr   szreadbuffer,sizeof   szreadbuffer  
  invoke rtlzeromemory,addr   @stsin,sizeof   @stsin  
  invoke recvfrom,_hsocket,addr   szreadbuffer,sizeof   szreadbuffer,\  
  0,addr   @stsin,addr   @dwsize  
  .if eax   != socket_error  
  invoke sendto,   hsocket,   addr   dwreturn2,   4,   \  
  0,addr   @stsin,sizeof   sockaddr_in  
  .if eax   == socket_error  
  invoke wsagetlasterror  
  .if eax   ==   wsaewouldblock  
  invoke getdlgitem,hwinmain,idok  
  invoke enablewindow,eax,false  
  .endif  
  .endif  
  invoke   setdlgitemtext,   hwinmain,   idc_status,   addr   szreadbuffer  
  .endif  
  ret  
  _recvdata   endp  
   
  _senddata   proc  
  local   @szbuffer[1024]:byte  
          local   @stsin:sockaddr_in  
          local   @btranslated:bool  
          local   @bsigned:bool  
          invoke   rtlzeromemory,   addr   @stsin,   sizeof   @stsin  
          invoke   getdlgitemtext,   hwinmain,   idc_server,   addr   @szbuffer,   sizeof   @szbuffer  
          invoke   inet_addr,   addr   @szbuffer  
          .if   eax   ==   inaddr_none  
          invoke   setdlgitemtext,   hwinmain,   idc_status,   addr   szerrorip  
          jmp   @f  
          .endif  
          mov   @stsin.sin_addr,   eax  
          mov   @stsin.sin_family,   af_inet  
          push   false  
          pop   @bsigned  
          invoke   getdlgitemint,   hwinmain,   idc_port,   addr   @btranslated,   @bsigned  
          mov   uport,   eax  
          mov   eax,   @btranslated  
          .if   eax   ==   false  
          invoke   setdlgitemtext,   hwinmain,   idc_status,   addr   szerrorport1  
          jmp   @f  
          .endif  
          .if   uport   ==   0  
                  invoke   setdlgitemtext,   hwinmain,   idc_status,   addr   szerrorport2  
                  jmp   @f  
          .endif  
          invoke   htons,   uport  
          mov   @stsin.sin_port,   ax  
          invoke   sendto,   hsocket,   addr   dwreturn1,   4,   0,   addr   @stsin,   sizeof   sockaddr_in  
          .if   eax   ==   socket_error  
          invoke   wsagetlasterror  
          .if   eax   ==   wsaewouldblock  
          invoke   getdlgitem,   hwinmain,   idok  
          invoke   enablewindow,   eax,   false  
          .endif  
          .endif  
          invoke   setdlgitemtext,   hwinmain,   idc_status,   addr   sztip1  
  @@:  
           
  ret  
  _senddata   endp  
   
   
   
  _dlgproc   proc   uses   ebx   esi   esi   hwnd,   umsg,   wparam,   lparam  
  mov   eax,   umsg  
  .if   eax   ==   wm_close  
  invoke   closesocket,   hsocket  
  invoke   wsacleanup  
  invoke   enddialog,   hwnd,   null  
  .elseif   eax   ==   wm_initdialog  
  push   hwnd  
  pop   hwinmain  
                                  invoke   setwindowpos,   hwinmain,   hwnd_topmost,   0,   0,   0,   0,   swp_nosize   or   swp_nomove  
  call   _init  
  .elseif   eax   ==   wm_command  
  mov   eax,   wparam  
  .if   ax   ==   idc_close  
  invoke   sendmessage,   hwinmain,   wm_close,   0,   0  
  .elseif   ax   ==   idok  
  invoke   setdlgitemtext,   hwinmain,   idc_status,   null  
  invoke   _senddata  
  .endif  
  .elseif   eax   ==   wm_udp  
  mov   eax,   lparam  
  .if   ax   ==   fd_read  
  invoke   _recvdata,   wparam  
  .elseif   ax   ==   fd_write  
  invoke   getdlgitem,   hwnd,   idok  
  invoke   enablewindow,   eax,   true  
  .endif  
  .else  
  xor   eax,   eax  
  ret  
  .endif  
  mov   eax,   true  
  ret  
  _dlgproc   endp  
   
   
  start:  
  invoke   getmodulehandle,   null  
  invoke   dialogboxparam,   eax,   dlg_main,   null,   _dlgproc,   null  
  invoke   exitprocess,   null  
  end   start

.
处理 SSI 文件时出错
© 2006-2008 All Rights Reserved