♣
+++++++++++++++++ UDP的简单问题 +++++++++++++++
我用sendto 向外发一个包,这时源端口是随机的,我如何能做到recvfrom 接收从服务器发来的回应包呢???不用csocket,直接用api,请问如何实现呢???
· 网友精彩回答:
sendto 向外发一个包时要用到一个hsocket句柄 在接受服务器方发回来的数据时fd_read消息的wparam 就是接受的hsocket
看看这个例子
http://cs.ecs.baylor.edu/~donahoo/practical/csockets/code/udpechoclientws.c
用raw socket应该可以解决你的问题
帮顶好发送的socket handle,然后响应fd_read消息好了
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和一个固定的端口绑定才行……
没办法,无连接的东西就是这个不好……
只要sendto过,就不需要bind了,因为sendto时系统已经为它分配了一个端口号了。只要用这个socket recvfrom即可。
udp不需要绑定,使用sendto的那个socket句柄recvfrom就行了
recvfrom是个堵塞函数,如果使用fd_read事件需要使用winsocket的异步消息函数
汇编写的要么? 看不懂的汇编代码我可以给你讲,要就加我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
- 更多问题:
- · 有没有相关工具?
- · 图书馆管理数据库该怎么做啊~????
- · vc怎样编译和运行?
- · 图书馆管理数据库该怎么做啊~????
- · 用JDBC连接SQL 2000 和MYSQL两种数据库在语句上是差不多的吗?
- · 图书馆管理数据库该怎么做啊~????
- · 删除重复的字符串行
- · 可恶的IE......
- · 求教oracle监听器与jsp冲突
- · 未将对象引用设置到对象的实例。
- · 请问,怎么把一个datatable存到换存中呢?
- · 我要用java 的相关技术做心跳检测的客户端,和用户的上下线请请求,知道原理的请进
- · 关于框架页面中如何实现基于表单的验证???特急!!
- · 怎样设置listview(report)控件选定的行的背景色
- · 大家帮我看看强类型DataSet的问题吧
- · 拜师学艺!!!

