当前位置: 首页 > article >正文

win32汇编环境,网络编程入门之一

运行效果

;win32汇编环境,网络编程入门之一
;网络编程,我们先要认识几个概念,理解一点原理。太高深的研究不了,先理解一点应用的知识。这时候,应该假设你已经具备初步的使用WIN32汇编编程的能力的。
;网络编程,需要实战才能理解,在这几个教程里,我们先学会怎么访问某个网站。
;连接一部电脑,首先需要知道它的地址。这个叫IP。所以,我们首先要知道某个电脑的IP地址,服务器也是电脑
;比如我们访问一个网站,要知道它的IP是什么。大多数时候,我们知道的是网址。
;可以把网址转换成IP。在网上找个域名转IP的网站,把网址输进去,查一下,它就会告诉我们这个网站的IP是什么,现在就知道IP了
;然后,理解一下端口的概念
;端口是电脑的哪个门。每部电脑有很多门,有的门连接打印机,有的门连接话筒,有的门让别人访问它,这些门就是端口
;网站一般的端口是80或8080
;第三个概念是SOCKET,叫套接字,这是网络连接的机制。机制是什么东西?网络连接其实涉及很多东西,这个SOCKET把这些东西封装在一起,帮我们弄好了,我们输入一些参数就可以了。
;当然,也可以仔细剖开来研究,这可以写成整部的书。我们暂时不需要理解这么深,先学会简单的用就可以了。
;这里先弄个IP地址控件来,然后尝试一下基本的连接网络。
;IP地址控件不是读出来的地址就可以用的,我们需要转换一下它。至于怎么转换,我们在代码里面理解。
;下面为asm文件
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.386 
.model flat,stdcall 
option casemap:none 

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Include 文件定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include    windows.inc 
include    user32.inc 
include    kernel32.inc 
include       wsock32.inc    ;需要添加的头文件,涉及socket

includelib user32.lib 
includelib kernel32.lib 
includelib wsock32.lib

; 自定义函数声明
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
DlgProc proto :DWORD,:DWORD,:DWORD,:DWORD   ;对话框窗口函数

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Equ 等值定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
ICO_MAIN    equ 1000    ;图标
IDC_IPA1    equ 1001
ID_BUTTON01    equ 41
TCP_PORT    equ 80          ;端口
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 数据段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data 
DlgName        db "MyDialog",0 
szErrIP           db "无效的服务器IP地址!",0
szErrConnect   db "无法连接到服务器!",0
szSucConnect   db "可以连接到服务器!",0
szIP           db "103.113.93.101",0        ;可派网站,也可以通过某个域名,在网站搜到这个域名的IP地址,放这里去尝试
szMsg          db "提示",0
szFrm          db "%d",0

.data? 
hInstance HINSTANCE             ? 

hW_IP     HWND       ?        ;IP地址控件的句柄
nGetIP    dd         ?        ;存放从IP地址控件取得的值的指针
hSocket      dd         ?
szServer  db 32 dup (?)
.const 

  
; 代码段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code 
start: 
         invoke GetModuleHandle, NULL 
         mov    hInstance,eax 
         invoke DialogBoxParam, hInstance, ADDR DlgName,NULL, addr DlgProc, NULL 
         invoke ExitProcess,eax 

DlgProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM 
        LOCAL    @stWsa:WSADATA
        LOCAL    @stSin:sockaddr_in
        LOCAL   @szBuffer[256]:byte
        LOCAL   @h01:byte,@h02:byte,@h03:byte,@h04:byte
        
        .if     uMsg == WM_INITDIALOG 
                invoke    LoadIcon,hInstance,ICO_MAIN           ;加载图标
            invoke    SendMessage,hWnd,WM_SETICON,ICON_BIG,eax
            invoke    WSAStartup,101h,addr @stWsa           ;这里的WSAStartup就是为了向操作系统说明,要使用哪个版本的socket。
            
            invoke  GetDlgItem,hWnd,IDC_IPA1              ;得到IP地址控件的句柄
                mov hW_IP,eax
                
                ;IP地址控件内的值,是1个32位的数。其中每8位占一个值,最高的字节为IP地址的开头值,最低的字节为结束值。以下面的IP地址:103.113.93.101为例。                        
                ;先把低2个字节的值即103和113赋值,然后用 shl 指令往左移位16位,就是占了高2位字节的位置,再把IP地址的后面两个值给它加上                        
                mov ah,103                        
                mov al,113                        
                shl eax,16                        
                mov ah,93                       
                mov al,101                       
                invoke SendMessage,hW_IP,IPM_SETADDRESS,0,eax    ;初始化设置控件里的IP地址值
        .elseif    uMsg ==    WM_COMMAND
            mov    ebx,wParam
                .if    bx ==    ID_BUTTON01
                invoke    RtlZeroMemory,addr @stSin,sizeof @stSin
                invoke  SendMessage,hW_IP,IPM_GETADDRESS,0,offset nGetIP    ;取出IP地址控件里的值的指针,并把这个指针值放在nGetIP里
                mov eax,dword ptr [nGetIP]                                  ;得到IP地址控件里的IP值
                
                mov @h04,al    ;@h04其实是IP地址中的 101                 
                mov @h03,ah    ;@h03其实是IP地址中的 93                
                shr eax,16     ;往右移16位,即把高2字节的内容推到低2字节里去,而空出来的位置则置0,用这种方法得到原来高2字节里面每个字节的值
                mov @h02,al    ;@h02其实是IP地址中的 113                 
                mov @h01,ah    ;@h01其实是IP地址中的 103
                ;invoke wsprintf,addr @szBuffer,addr szFrm,@h01
                ;invoke    MessageBox,hWnd,addr @szBuffer,NULL,MB_OK or MB_ICONINFORMATION
                
                ;开始创建IP字节序,其实就是把4个字节的顺序换换。这里需要的是网络字节序,它的顺序,可以看下面代码。
                ;相当于把原来的顺序 103.113.93.101 转换为 101.93.113.103,这是后面的 sockaddr_in 需要的格式
                mov bl,@h03
                mov bh,@h04
                shl ebx,16
                mov bl,@h01
                mov bh,@h02

                mov    @stSin.sin_addr,ebx             ;把IP地址转换成的网络字节序给 @stSin,
                mov    @stSin.sin_family,AF_INET       ;指定是IPv4 的地址
                invoke    htons,TCP_PORT                  ;用htons函数把端口号进行转换,
                mov    @stSin.sin_port,ax              ;将其低2字节值给sin_port成员

                invoke    socket,AF_INET,SOCK_STREAM,0    ;支持可靠的面向连接的字节流通信
                mov    hSocket,eax
                
                ; 连接到服务器
                invoke    connect,hSocket,addr @stSin,sizeof @stSin
                .if eax == SOCKET_ERROR   ;如果有错误,则返回SOCKET_ERROR
                             invoke    MessageBox,hWnd,addr szErrConnect,NULL,MB_OK or MB_ICONSTOP
                    .elseif eax == 0          ;如果没有错,则返回0.没有错也不是马上连接上,它需要一点时间,所以可能会造成卡顿,这取决于网络。所以,我们一般把连接过程放在一个线程里面,这样就不会卡住主程序。
                         invoke    MessageBox,hWnd,addr szSucConnect,NULL,MB_OK or MB_ICONINFORMATION       
                .endif
                ;至于怎么判断是否连接到了,不用急,在下一教程里我们再学。
            .endif        
        .elseif uMsg == WM_CLOSE     ;退出程序时记得清除套接字
                .if    ! hSocket    ;如果socket创建失败,则清除它,否则先关闭,再清除
            invoke    WSACleanup
            invoke    EndDialog,hWnd,NULL
        .else
            invoke    closesocket,hSocket
            xor    eax,eax
            mov    hSocket,eax
            invoke    WSACleanup
            invoke    EndDialog,hWnd,NULL
        .endif
        .else 
                mov eax,FALSE 
                ret 
        .endif 
                mov eax,TRUE 
        ret 
DlgProc endp 

end start 
 

;下面为rc文件内容
#include "resource.h"                   //提示缺少该文件,可以在资源里下载
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#define       ICO_MAIN        1000    //图标
#define    IDC_IPA1        1001
#define    ID_BUTTON01     41
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
ICO_MAIN    ICON        "Main.ico"
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//定义对话框
MyDialog DIALOG 10, 10, 210, 40 
STYLE  DS_CENTER | WS_CAPTION | WS_MINIMIZEBOX | 
WS_SYSMENU | WS_VISIBLE | WS_OVERLAPPED | DS_MODALFRAME | DS_3DLOOK 
CAPTION "对话框程序模版" 
FONT 11, "方正姚体"
BEGIN 
     CONTROL "输入IP地址:", -1, "Static", WS_CHILD | WS_VISIBLE, 10, 10, 50, 20
     CONTROL "",IDC_IPA1,"SysIPAddress32",WS_CHILDWINDOW|WS_VISIBLE|WS_TABSTOP,60,10,70,10
     PUSHBUTTON      "登录网站", ID_BUTTON01,  135,8,60,12
END 


 


http://www.kler.cn/a/582258.html

相关文章:

  • Vue 3 中,将静态资源(如图片)转换为 URL
  • Orale数据文件加错位置,你直接rm引发的故障
  • 【RAG】RAG 系统的基本搭建流程(ES关键词检索示例)
  • maven的项目构建
  • Web3.0 从入门到实战:一站式开发指南
  • 在MATLAB中实现PID控制仿真
  • Vue3——Fragment
  • MVCC实现原理
  • Express + MongoDB 实现登录验证码
  • 【踩坑记录】MAC M4 mini 系统初始化
  • Express + MongoDB + multer 解决文件上传 originalname 中文乱码
  • 量子计算如何颠覆能源优化领域:从理论到实践
  • 02C#基本结构篇(D4_注释-访问修饰符-标识符-关键字-运算符-流程控制语句)
  • TinyVue 的 DatePicker 组件支持日期面板单独使用啦!
  • 在虚拟机VMware上安装CENTOS7-图文教程
  • ES Filter Query 区别
  • QT系列教程(20) Qt 项目视图便捷类
  • 界面控件Kendo UI for Vue 2024 Q4亮点 - 增强图表的数据模板、导航功能
  • 表、索引统计信息锁定和解锁
  • Burpsuite使用笔记