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

qq_13939330 2005-07-30 10:29:16
我用Sendto 向外发一个包,这时源端口是随机的,我如何能做到Recvfrom 接收从服务器发来的回应包呢???不用CSocket,直接用API,请问如何实现呢???
...全文
148 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
surstar 2005-08-02
  • 打赏
  • 举报
回复
服务器方:
.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_STATUS equ 2001
IDC_CLOSE Equ 2002
IDC_PORT Equ 2003
IDC_CREATE Equ 2004
WM_UDP Equ WM_USER + 100

.Data?
hWinMain DD ?
hSocket dd ?
szReadBuffer DB 1024 Dup (?)
szBuffer DB 1024 Dup (?)
uPort DD ?
bSuccess BOOL ?
stSin sockaddr_in <?>
count DD ?
;use to debug

szDebugBuffer DB 1024 Dup(?)
.Const
szErrBind db '老大!一个端口只能帮定一个UDP应用,检查一下是否有其他应用程序在使用该端口',0
szFormat DB '【客户端#%d】- %s', 0DH, 0AH, 0
szErrorPort1 DB 'Port填写错误,必须为非负数', 0
szErrorPort2 DB '获取端口失败!', 0
szTip1 DB '等待接受数据', 0
szTip2 DB '有人发了数据包过来,接受到的第:%d 包', 0
szTip3 DB '客户方已经收到了服务器发的确认', 0
szTip4 DB '服务向客户方发的确认包丢失', 0
szHasRecv DB '服务器方收到了数据!', 0
szDebugFormat DB '客户方发出数据的port:%d', 0



.Code
_SendData Proc
Invoke sendto, hSocket, Addr szHasRecv, SizeOf szHasRecv, \
0, Addr stSin, SizeOf sockaddr_in
Ret
_SendData EndP

_RecvData Proc _hSocket
Local @dwRecv, @dwStructSize
Local @dwCount

mov @dwStructSize,sizeof sockaddr_in
invoke RtlZeroMemory,addr szReadBuffer,sizeof szReadBuffer
Invoke RtlZeroMemory, Addr stSin, SizeOf stSin
invoke recvfrom,_hSocket,addr szReadBuffer,sizeof szReadBuffer,\
0, Addr stSin, Addr @dwStructSize
.If Eax != SOCKET_ERROR
.If DWord Ptr szReadBuffer == -1
Inc count
Invoke RtlZeroMemory, Addr szBuffer, SizeOf szBuffer
Invoke wsprintf, Addr szBuffer, Addr szTip2, DWord Ptr count
Invoke SetDlgItemText, hWinMain, IDC_STATUS, Addr szBuffer
Mov Esi, Offset stSin
Assume Esi:Ptr sockaddr_in
Invoke ntohs, Word Ptr [Esi].sin_port
;Invoke wsprintf, Addr szDebugBuffer, Addr szDebugFormat, Ax
;Invoke MessageBox, NULL, Addr szDebugBuffer, Addr szDebugBuffer, MB_OK
.ElseIf DWord Ptr szReadBuffer == -2
;客户方已经收到了确认
Invoke SetDlgItemText, hWinMain, IDC_STATUS, Addr szTip3
.Else
Invoke SetDlgItemText, hWinMain, IDC_STATUS, Addr szTip4
.EndIf
.EndIf
Ret
_RecvData EndP

_Init Proc
Local @stWsa:WSADATA
Local @stSin:sockaddr_in
Local @bTranslated:BOOL
Local @bSigned:BOOL

invoke WSAStartup,101h,addr @stWsa
invoke socket,AF_INET,SOCK_DGRAM,0
mov hSocket,eax
Invoke WSAAsyncSelect, hSocket, hWinMain, WM_UDP, FD_READ

Invoke RtlZeroMemory, Addr stSin, SizeOf stSin
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 wsprintf, Addr szDebugBuffer, Addr szDebugFormat, dword ptr @stSin.sin_port
;Invoke MessageBox, NULL, Addr szDebugBuffer, NULL, 0
mov @stSin.sin_family,AF_INET
mov @stSin.sin_addr,INADDR_ANY
invoke bind,hSocket,addr @stSin,sizeof @stSin
.if eax == SOCKET_ERROR
invoke MessageBox,hWinMain,addr szErrBind,NULL,\
MB_OK or MB_ICONWARNING
invoke SendMessage,hWinMain,WM_CLOSE,0,0
.EndIf

Push TRUE
Pop bSuccess
Invoke SetDlgItemText, hWinMain, IDC_STATUS, Addr szTip1
@@:
Ret
_Init EndP

_ProcDlgMain Proc Uses Ebx Edi Esi hWnd, wMsg, wParam, lParam

mov eax,wMsg
.If Eax == WM_UDP
mov eax,lParam
.If Ax == FD_READ
Invoke GetDlgItem, hWinMain, IDOK
Invoke EnableWindow, Eax, TRUE
invoke _RecvData,wParam
.endif
.ElseIf Eax == WM_CLOSE
invoke closesocket,hSocket
invoke WSACleanup
invoke EndDialog,hWinMain,NULL
.ElseIf Eax == WM_INITDIALOG
Push 0
Pop count
push hWnd
Pop hWinMain
Invoke SetWindowPos, hWinMain, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE Or SWP_NOMOVE
Invoke GetDlgItem, hWinMain, IDOK
Invoke EnableWindow, Eax, FALSE
Push FALSE
Pop bSuccess

.ElseIf Eax == WM_COMMAND
Mov Eax, wParam
.If Ax == IDC_CLOSE
Invoke SendMessage, hWinMain, WM_CLOSE, 0, 0
.ElseIf Ax == IDOK
Invoke _SendData
Invoke GetDlgItem, hWinMain, IDOK
Invoke EnableWindow, Eax, FALSE
.ElseIf Ax == IDC_CREATE
Call _Init
.If bSuccess == TRUE
Invoke GetDlgItem, hWinMain, IDC_CREATE
Invoke EnableWindow, Eax, FALSE
Invoke GetDlgItem, hWinMain, IDC_PORT
Invoke EnableWindow, Eax, FALSE
.EndIf
.EndIf
.Else
mov eax,FALSE
ret
.endif
mov eax,TRUE
ret

_ProcDlgMain endp
start:
invoke GetModuleHandle,NULL
invoke DialogBoxParam,eax,DLG_MAIN,NULL,offset _ProcDlgMain,0
invoke ExitProcess,NULL
End start
surstar 2005-08-02
  • 打赏
  • 举报
回复
汇编写的要么? 看不懂的汇编代码我可以给你讲,要就加我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
吹泡泡的小猫 2005-08-01
  • 打赏
  • 举报
回复
UDP不需要绑定,使用sendto的那个socket句柄recvfrom就行了

recvfrom是个堵塞函数,如果使用FD_READ事件需要使用Winsocket的异步消息函数
qq_13939330 2005-08-01
  • 打赏
  • 举报
回复
谁知道有关UDP完成端口的例子,马上接贴了!
softrain 2005-08-01
  • 打赏
  • 举报
回复
只要sendto过,就不需要bind了,因为sendto时系统已经为它分配了一个端口号了。只要用这个SOCKET recvfrom即可。
goodboyws 2005-07-31
  • 打赏
  • 举报
回复
用Raw socket应该可以解决你的问题
newbiestar 2005-07-31
  • 打赏
  • 举报
回复
没办法,无连接的东西就是这个不好……
newbiestar 2005-07-31
  • 打赏
  • 举报
回复
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和一个固定的端口绑定才行……
oyljerry 2005-07-31
  • 打赏
  • 举报
回复
帮顶好发送的socket handle,然后响应FD_READ消息好了
masterz 2005-07-30
  • 打赏
  • 举报
回复
看看这个例子
http://cs.ecs.baylor.edu/~donahoo/practical/CSockets/code/UDPEchoClientWS.c
surstar 2005-07-30
  • 打赏
  • 举报
回复
Sendto 向外发一个包时要用到一个hSocket句柄 在接受服务器方发回来的数据时FD_READ消息的wParam (具体是lparam 还是是wParam 一时记得不是很清楚了) 就是接受的hSocket

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧