📄 server.asm
字号:
include .\head.inc
client Struct
hsocket HANDLE ?
nickname db 10 dup(?)
nextlink dd NULL
client endS
ModalDlgProc PROTO :DWORD,:DWORD,:DWORD,:DWORD
GetSite PROTO :DWORD,:DWORD,:DWORD
make_skt PROTO :dword
receive_pkt PROTO :dword,:dword
addchain PROTO:dword
removechain PROTO:dword
AddNickName PROTO :dword,:dword
delay PROTO
GetTalker PROTO :dword,:dword
.const
IDD_SERVER equ 102
IDC_EDIT equ 1000
IDC_STATICCOUNT equ 1001
IDC_LIST equ 1004
UM_SOCK equ WM_USER+100h
DEFAULT_PORT equ 5150
.data
Prompt db "TCP/IP",0
TitleName db "服务器端",0
StartupError db "套接字初始化错误!",0
SocketError db "套接字创建错误!",0
SelectError db "异步选择模式错误!",0
BindError db "绑定错误!",0
AcceptError db "拒绝客户请求!",0
pLinkHead dd NULL
CountOL dd 0
NickNameMark db "@#@",0
PrivateMark db "@$@",0
DeleteMark db "@!@",0
Crlf db 0dh,0ah,0
NickNameBuffer db 20 dup (0)
say db "说:",0
.data?
hInstance HINSTANCE ?
hsocket HANDLE ?
hList HANDLE ?
hEdit HANDLE ?
hHeap dd ?
RecvBuffer db 1024 dup (?)
DisplayBuffer db 1200 dup (?)
talker db 5 dup (?)
buffer db 10 dup (?)
.code
start:
invoke GetModuleHandle, NULL
mov hInstance,eax
invoke GetProcessHeap
mov hHeap,eax
invoke DialogBoxParam,NULL,IDD_SERVER,NULL,addr ModalDlgProc,NULL
invoke ExitProcess,eax
ModalDlgProc proc hWnd:dword,uMsg:dword,wParam:dword,lParam:dword
local hnewsocket:HANDLE
.if uMsg==WM_INITDIALOG
invoke GetDlgItem,hWnd,IDC_LIST
mov hList,eax
invoke GetDlgItem,hWnd,IDC_EDIT
mov hEdit,eax
invoke make_skt,hWnd
.elseif uMsg==WM_CLOSE
.if hsocket
invoke closesocket,hsocket
.endif
invoke WSACleanup
invoke EndDialog,hWnd,NULL
.elseif uMsg==UM_SOCK
mov eax,lParam
.if ax==FD_ACCEPT
invoke accept,wParam,0,0
mov hnewsocket,eax
invoke WSAAsyncSelect,eax,hWnd,UM_SOCK,FD_READ or FD_CLOSE
.if eax==INVALID_SOCKET
invoke closesocket,hsocket
invoke MessageBox,hWnd,addr AcceptError,addr TitleName,MB_OK
invoke SendMessage,hWnd,WM_CLOSE,0,0
.endif
invoke addchain,hnewsocket
inc CountOL
invoke SetDlgItemInt,hWnd,IDC_STATICCOUNT,CountOL,FALSE
.elseif ax==FD_READ
invoke receive_pkt,wParam,hWnd
.elseif ax==FD_CLOSE
dec CountOL
invoke SetDlgItemInt,hWnd,IDC_STATICCOUNT,CountOL,FALSE
invoke removechain,wParam
.endif
.elseif uMsg==WM_COMMAND
mov eax,wParam
.else
mov eax,FALSE
ret
.endif
mov eax,TRUE
ret
ModalDlgProc endp
make_skt proc hwnd:dword
local wsaData:WSADATA
local sin:sockaddr_in
invoke WSAStartup,101h,addr wsaData
.if eax
invoke MessageBox,hwnd,addr StartupError,addr TitleName,MB_OK
invoke SendMessage,hwnd,WM_CLOSE,0,0
.endif
invoke socket ,AF_INET,SOCK_STREAM,0
.if eax==INVALID_SOCKET
invoke MessageBox,hwnd,addr SocketError,addr TitleName,MB_OK
invoke SendMessage,hwnd,WM_CLOSE,0,0
.endif
mov hsocket,eax
invoke WSAAsyncSelect,hsocket,hwnd,UM_SOCK,FD_ACCEPT
.if eax==SOCKET_ERROR
invoke WSAGetLastError
.if eax!=WSAEWOULDBLOCK
invoke closesocket,hsocket
invoke MessageBox,hwnd,addr SelectError,addr TitleName,MB_OK
invoke SendMessage,hwnd,WM_CLOSE,0,0
.endif
.endif
invoke RtlZeroMemory,addr sin,sizeof sin
invoke htons, DEFAULT_PORT
mov sin.sin_port,ax
mov sin.sin_family,AF_INET
mov sin.sin_addr.S_un,INADDR_ANY
invoke bind,hsocket,addr sin,sizeof sockaddr_in
.if eax
invoke closesocket,hsocket
invoke MessageBox,hwnd,addr BindError,addr TitleName,MB_OK
invoke SendMessage,hwnd,WM_CLOSE,0,0
.endif
invoke listen,hsocket,8
ret
make_skt endp
addchain proc uses edi hs:dword
local ptemp:dword
invoke HeapAlloc,hHeap,HEAP_ZERO_MEMORY,sizeof client
mov ptemp,eax
mov edi,eax
assume edi:ptr client
push hs
pop [edi].hsocket
.if pLinkHead
push pLinkHead
pop [edi].nextlink
.endif
push ptemp
pop pLinkHead
assume edi:nothing
ret
addchain endp
removechain proc uses edi esi hs:dword
local p:dword
local len:dword
mov NickNameBuffer,0
mov edi,pLinkHead
assume edi:ptr client
mov eax,hs
.if [edi].hsocket==eax
push [edi].nextlink
pop pLinkHead
invoke SendMessage,hList,LB_FINDSTRING,0,addr [edi].nickname
invoke SendMessage,hList,LB_DELETESTRING,eax,0
invoke lstrcpy,addr NickNameBuffer,addr [edi].nickname
invoke HeapFree,hHeap,HEAP_ZERO_MEMORY,edi
.else
.while edi
mov eax,hs
.if [edi].hsocket==eax
push esi
mov esi,p
assume esi:ptr client
.if [esi].nextlink!=NULL
push [edi].nextlink
pop [esi].nextlink
invoke SendMessage,hList,LB_FINDSTRING,0,addr [edi].nickname
invoke SendMessage,hList,LB_DELETESTRING,eax,0
invoke lstrcpy,addr NickNameBuffer,addr [edi].nickname
invoke HeapFree,hHeap,HEAP_ZERO_MEMORY,edi
.break .if (TRUE)
.else
mov [esi].nextlink,NULL
.endif
assume esi:nothing
pop esi
.endif
mov p,edi
push [edi].nextlink
pop edi
.endw
.endif
invoke lstrcat,addr NickNameBuffer,addr DeleteMark
invoke lstrlen,addr NickNameBuffer
mov len,eax
mov edi,pLinkHead
.while edi
invoke send,[edi].hsocket,addr NickNameBuffer,len,0
push [edi].nextlink
pop edi
.endw
assume edi:nothing
ret
removechain endp
receive_pkt proc uses esi edi hs:dword,hwnd:HANDLE
local len:dword
mov talker,0
mov DisplayBuffer,0
invoke RtlZeroMemory,addr RecvBuffer,1024
invoke recv ,hs,addr RecvBuffer,1024,0
invoke InString,1,addr RecvBuffer,addr NickNameMark
.if eax
invoke lstrlen,addr RecvBuffer
mov len,eax
mov edi,pLinkHead
assume edi:ptr client
.while edi
invoke send,[edi].hsocket,addr RecvBuffer,len,0;每个客户端的列表增加新登录的昵称。
push [edi].nextlink
pop edi
.endw
mov edi,pLinkHead
.while edi
mov eax,hs
.if [edi].hsocket!=eax
mov NickNameBuffer,0
invoke lstrcpy,addr NickNameBuffer,addr [edi].nickname
invoke lstrcat,addr NickNameBuffer,addr NickNameMark
invoke lstrlen,addr NickNameBuffer
invoke send,hs,addr NickNameBuffer,eax,0;新登录的客户端的列出在线昵称。
.endif
push [edi].nextlink
pop edi
invoke delay
.endw
assume edi:nothing
sub len,3
lea esi,RecvBuffer
add esi,len
mov byte ptr [esi],0
invoke AddNickName,hs,addr RecvBuffer;补加套接字对应的昵称
ret
.endif
invoke GetTalker, hs,addr talker
invoke lstrcat,addr DisplayBuffer,addr talker
invoke lstrcat,addr DisplayBuffer,addr say
invoke lstrcat,addr DisplayBuffer,addr RecvBuffer
invoke InString,1,addr DisplayBuffer,addr PrivateMark
.if eax
invoke GetSite,addr PrivateMark,addr DisplayBuffer,4
dec eax
lea esi,DisplayBuffer
add esi,eax
mov byte ptr[esi],0
invoke lstrcat,addr DisplayBuffer,addr Crlf
invoke lstrlen,addr DisplayBuffer
invoke send,hs,addr DisplayBuffer,eax,0
mov edi,pLinkHead
assume edi:ptr client
.while edi
mov buffer,0
invoke lstrcat,addr buffer,addr PrivateMark
invoke lstrcat,addr buffer,addr [edi].nickname
invoke lstrlen,addr buffer
invoke InString,eax,addr RecvBuffer,addr buffer
.if eax
invoke lstrlen,addr DisplayBuffer
invoke send,[edi].hsocket,addr DisplayBuffer,eax,0
.endif
push [edi].nextlink
pop edi
.endw
assume edi:nothing
.else
invoke lstrcat,addr DisplayBuffer,addr Crlf
mov edi,pLinkHead
assume edi:ptr client
.while edi
invoke lstrlen,addr DisplayBuffer
invoke send,[edi].hsocket,addr DisplayBuffer,eax,0
push [edi].nextlink
pop edi
.endw
assume edi:nothing
.endif
invoke SendMessage,hEdit,EM_SETSEL,-1,-1
invoke SendMessage,hEdit,EM_REPLACESEL,0,addr DisplayBuffer
ret
receive_pkt endp
GetTalker proc uses edi hs:dword,TalkerAddr:dword
mov edi,pLinkHead
assume edi:ptr client
.while edi
mov eax,hs
.if [edi].hsocket==eax
invoke lstrcpy,TalkerAddr,addr [edi].nickname
.break .if(TRUE)
.endif
push [edi].nextlink
pop edi
.endw
assume edi:nothing
ret
GetTalker endp
AddNickName proc hs:dword,NameAddr:dword
invoke SendMessage,hList,LB_ADDSTRING,NULL,NameAddr
mov edi,pLinkHead
assume edi:ptr client
.while edi
mov eax,hs
.if [edi].hsocket==eax
invoke lstrcpy,addr [edi].nickname,NameAddr
.break .if (TRUE)
.endif
push [edi].nextlink
pop edi
.endw
assume edi:nothing
ret
AddNickName endp
GetSite proc proc uses esi edi source:dword ,dest:dword,Count:dword
local len:dword
local buff[100]:byte
mov esi,source
mov edi,dest
invoke lstrlen,edi
mov len,eax
.while TRUE
mov al,byte ptr [esi]
mov ecx,len
repne scasb
.if zero?
dec edi
invoke lstrcpyn,addr buff,edi,Count
invoke lstrcmp,addr buff ,source
.if !eax
sub edi,dest
inc edi
mov eax,edi
.break .if (TRUE)
.else
inc edi
invoke lstrlen,edi
mov len,eax
.endif
.else
mov eax,FALSE
.break.if (TRUE)
.endif
.endw
ret
GetSite endp
delay proc
pushad
mov ecx,3fffffffh
again:
loop again
popad
ret
delay endp
end start
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -