茵蒂克丝

基础概念

IP 地址

IP 是英文 Internet Protocol (网络之间互连的协议)的缩写,也就是为计算机网络相互连接进行通信而设计的协议。任一系统,只要遵守 IP协议就可以与因特网互连互通。

所谓IP地址就是给每个遵循tcp/ip协议连接在Internet上的主机分配的一个32bit地址。按照TCP/IP协议规定,IP地址用二进制来表示,每个IP地址长32bit,比特换算成字节,就是4个字节。为了方便人们的使用,IP地址经常被写成十进制的形式,中间使用符号 “.” 分开不同的字节,如:192.168.1.1。在因特网中,主机的标识便是它ip地址。

常见的获取服务器ip的方法是使用系统自带的ping命令。例,打开cmd输入:

ping www.baidu.com

输出:

其中的 115.239.210.27 就是baidu服务器的地址了

服务端与客户端

服务端与客户端在计算机的世界里,凡是提供服务的一方我们称为服务端(Server),而接受服务的另一方我们称作客户端(Client)。

网站提供网页数据的服务,使用者接受网站所提供的数据服务,所以使用者在这里就是客户端,响应使用者要求的网站即称为服务端。

不过客户端及服务端的关系不见得一定建立在两台分开的机器上,同一台机器中也有这种主从关系的存在,提供服务的服务端及接受服务的客户端也有可能都在同一台机器上。

例如我们在提供网页的服务器上执行浏览器浏览本机所提供的网页,这样在同一台机器上就同时扮演服务端及客户端。

Socket

socket的英文原义是“孔”或“插座”。作为4BDS UNIX的进程通信机制,取后一种意思。通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄。

Scoket程勋分为服务端与客户端,服务端程序监听端口,等待客户端程序的连接。客户端程序发起连接,等待服务端的相应。客户端想要连接上服务端的话,需要 知道服务端的ip地址。

例如,客户想要访问百度网站的首页,通过浏览器访问http://www.baidu.com。浏览器发出请求之后,先是DNS服务器将百度的域名解析成ip地址之后,访问到ip地址为115.239.210.27服务器的80端口(http协议默认在80端口),请求发送后,百度的服务器作为响应将页面的源代码发送至客户端(通过浏览器右键->源代码,或者ctrl+u可以看到服务器返回的页面源代码),随后浏览器将源代码渲染成页面。这样用户就看到了百度网站的首页。

头文件和库文件

在windows系统上,当前的Windows Socket接口是Windows Sockets 2,所有接口函数都是有Ws2_32.dll导出。在进行程序设计时,祥光的数据类型、结构定义、函数声明等卫浴头文件winsock2.h中,编译时需要包含此文件,并且连接到库Ws2_32.lib。

常用函数

常见的socket函数

  • WSAStartup 初始化Ws2_32.lib库
  • WSACleanup 关闭Ws2_32.lib库
  • Socket 创建socket
  • closesocket 关闭socket
  • sockaddr和sockaddr_in 结构体socket地址
  • bind 绑定
  • listen 监听
  • accept 接收
  • connect 连接
  • send 发送
  • recv 获取返回

    WSAStartup () 函数

    WSAStartup函数的功能使加载Ws2_32.dll等Socket程序运行的环境。在程序初始化后,Socket程序运行所依赖的动态链接库不一定已经在家,WSAStartup保证了Socket 动态链接库的加载。

    1
    2
    3
    4
    int

    WSAStartup(
    __in
    WORD

    wVersionRequested,
    __out
    LPWSADATA lpWSAData
    );

    参数一 wVersionRequested

    Socket程序库的版本,一般使用MAKEWORD(2,2)宏生成。

    参数二 lpWSAData

    输出参数,指向 WSADATA 结构的指针,用于返回Socket库初始化的信息。

    返回值 用来判断程序是否成功加载

    WSACleanup () 函数

    与 WSAStartup 相反, WSACleanup 释放Ws2_32.dll,函数无参数。

    Socket () 函数

    Socket函数的功能是建立一个绑定到制定协议和传输类型的Socket。

    1
    2
    3
    4
    5
    SOCKET
    WSAAPI socket(
    __in
    int

    af,
    __in
    int

    type,
    __in
    int

    protocol
    );

    参数一 af

    address family的缩写,制定该Socket使用哪一种类型的网络地址。可以是IPv4(AF_INET),也可以是IPv6(AF_INET6)、蓝牙(AF_BTM)、NetBios(AF_NETBIOS)等。

    参数二 type

    设置传输类型,常见类型有 SOCK_STREAM、 SOCK_DGRAM、 SOCK_RAM、 SOCK_SEQPACKET 等。SOCK_STREAM 类型是基于连接的(TCP),所收的数据时数据流形式的,传输层的数据包已经经过处理。SOCK_DGRAM是基于报文(UDP)。如果制定为SOCK_RAM,那么可以建立原始套接字,所收到的数据是以数据包(包括包头)的形式存在的。

    参数三 protocol

    设置传输协议,常用的协议为 IPPROTO_TCP 和 IPPROTO_UDP。

    colsesocket() 函数

    与 socket 函数对应,用于关闭 socket

    1
    2
    3
    int

    WSAAPI closesocket(
     __in
    SOCKET s
     );

    参数一 s

    指定要关闭的socket

    sockaddr 和 sockaddr_in 结构体

    sockaddr、 SOCKADDR、 sockaddr_in、 SOCKADDR_IN 这
    几个结构用于表示地址很端口。在IPv4下,这几个结构体是可以通用的。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    typedef

    struct

    sockaddr {
     
    #if
    (_WIN32_WINNT < 0x0600)
        u_short
    sa_family;
    #else
        ADDRESS_FAMILY
    sa_family;
    //
    Address family.
    #endif
    //(_WIN32_WINNT < 0x0600)
     
        CHAR

    sa_data[14];
    //
    Up to 14 bytes of direct address.
    }
    SOCKADDR, *PSOCKADDR, FAR *LPSOCKADDR;
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    typedef

    struct

    sockaddr_in {
     
    #if(_WIN32_WINNT
    < 0x0600)
        short

    sin_family;
    #else
    //(_WIN32_WINNT < 0x0600)
        ADDRESS_FAMILY
    sin_family;
    #endif
    //(_WIN32_WINNT < 0x0600)
     
        USHORT

    sin_port;
        IN_ADDR
    sin_addr;
        CHAR

    sin_zero[8];
    }
    SOCKADDR_IN, *PSOCKADDR_IN;

    bind() 函数

    服务器端,将Socket与网络地址和端口绑定起来,函数原型如下:

    1
    2
    3
    4
    5
    int

    WSAAPI bind(
    __in
    SOCKET s,
    __in_bcount(namelen)
    const

    struct

    sockaddr FAR * name,
    __in
    int

    namelen
    );

    参数一 s

    要绑定的socket

    参数二 name

    要绑定的网络地址结构体

    参数三 namelen

    name参数所指向的结构体的大小

    listen() 函数

    设置 socket 的状态为监听,使客户端程序可以进行连接,函数原型:

    1
    2
    3
    4
    int

    WSAAPI listen(
    __in
    SOCKET s,
    __in
    int

    backlog
    );

    参数一 s

    绑定的socket

    参数二 backlog

    指定最大的连接数

    accept() 函数

    接受客户端的连接

    1
    2
    3
    4
    5
    SOCKET
    WSAAPI accept(
    __in
    SOCKET s,
    __out_bcount_opt(*addrlen)
    struct

    sockaddr FAR * addr,
    __inout_opt
    int

    FAR * addrlen
    );

    参数一 s

    正在监听的socket,该 socket 使用 listen() 设置。

    参数二 addr (可选)

    指针,指向一缓冲区,其中接收为通讯层所知的连接实体的地址。Addr参数的实际格式由套接口创建时所产生的地址族确定。

    参数三 addrlen (可选)

    指针,指向存有addr地址长度的整形数。

    返回:

    成功:非负描述字

    失败:-1

    accept 默认会阻塞进程,直到有客户端建立连接后返回,它返回的是连接用的 socket 。如果 accept 成功返回,则服务器与客户已经正确建立连接了,此时服务器通过 accept 返回的 socket 来完成与客户的通信。

    connect() 函数

    connect函数的功能使与服务器建立连接。这个函数只能由客户端程序调用。

    1
    2
    3
    4
    5
    int

    WSAAPI connect(
    __in
    SOCKET s,
    __in_bcount(namelen)
    const

    struct

    sockaddr FAR * name,
    __in
    int

    namelen
    );

    参数一 s

    由 socket 函数建立的套接字。

    参数二 name

    指向sockaddr结构体指针,包括了所要连接的服务端的地址和端口等。

    参数三 namelen

    sockaddr结构的长度

    send() 函数

    向连接的另一端发送数据,不论是客户还是服务器应用程序都用 send 函数来向 TCP 连接的另一端发送数据。

    1
    2
    3
    4
    5
    6
    int

    WSAAPI send(
    __in
    SOCKET s,
    __in_bcount(len)
    const

    char

    FAR * buf,
    __in
    int

    len,
    __in
    int

    flags
    );

    参数一 s

    指定发送端socket描述符。

    参数二 *buf

    指明存放要发送的数据的缓冲区。

    参数三 len

    指明实际要发送的数据的字节数。

    参数四 flags

    指明发送的方法,常见宏MSG_DONTROUTE、MSG_OOB等,一般置0。

    将*buf指向的字符串发送至客户端

    recv() 函数

    不论是客户还是服务器应用程序都用 recv 函数 从 TCP 连接的另一端接收数据。

    1
    2
    3
    4
    5
    6
    int

    WSAAPI recv(
    __in
    SOCKET s,
    __out_bcount_part(len,
    return)
    __out_data_source(NETWORK)
    char

    FAR * buf,
    __in
    int

    len,
    __in
    int

    flags
    );

    参数一 s

    指定接收端socket描述符;

    参数二 *buf

    指明一个缓冲区,该缓冲区用来存放recv函数接收到的数据;

    参数三 len 

    指明buf的长度;

    参数四 flags

    指明接收的方法,常见宏 MSG_DONTROUTE、 MSG_OOB 等,一般置0。

    获取到客户端返回的字符串并将其写入到buf中

    简单的 socket 通信示例

    服务端(Server)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    #include
    <Winsock2.h>
    #include
    <stdio.h>
    #pragma
    comment(lib, "ws2_32.lib")
     
    void

    main()
    {
        int

    err;
    //
    错误信息
        int

    len;
     
        char

    sendBuf[100];
    //
    发送至客户端的字符串
        char

    recvBuf[100];
    //
    接受客户端返回的字符串
     
        SOCKET
    sockServer;    
    //
    服务端 Socket
        SOCKADDR_IN
    addrServer;
    //
    服务端地址
        SOCKET
    sockClient;    
    //
    客户端 Scoket
        SOCKADDR_IN
    addrClient;
    //
    客户端地址
     
        WSADATA
    wsaData;      
    //
    winsock 结构体
        WORD

    wVersionRequested;
    //
    winsock 的版本
     
        //
    配置 Windows Socket版本
        wVersionRequested
    = MAKEWORD( 2, 2 );
     
        //
    初始化 Windows Socket
        err
    = WSAStartup( wVersionRequested, &wsaData );
     
        if

    ( err != 0 )
        {
            //
    启动错误,程序结束
            return;
        }
     
        /*
         *
    确认WinSock DLL支持2.2
         *
    请注意如果DLL支持的版本大于2.2至2.2
         *
    它仍然会返回wVersion2.2的版本
         */
     
        if

    ( LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2 )
        {
            //
    启动错误,程序结束
            WSACleanup();
    //
    终止Winsock 2 DLL (Ws2_32.dll) 的使用
            return;
        }
     
        //
    定义服务器端socket
        sockServer
    = socket(AF_INET, SOCK_STREAM, 0);
     
        // 
    设置服务端 socket
        addrServer.sin_addr.S_un.S_addr
    = htonl(INADDR_ANY);
    //
    本机IP
        addrServer.sin_family
    = AF_INET;                  
    //
    协议类型是INET
        addrServer.sin_port
    = htons(6000);                
    //
    绑定端口6000
     
        //
    将服务器端socket绑定在本地端口
        bind(sockServer,
    (SOCKADDR *)&addrServer,
    sizeof(SOCKADDR));
     
        //
    Listen 监听端口
        listen(sockServer,
    5);
    //
    5 为等待连接数目
     
        printf("服务器已启动:\n监听中...\n");
     
        len
    =
    sizeof(SOCKADDR);
     
        //
    accept 会阻塞进程,直到有客户端连接上来为止
        sockClient
    = accept(sockServer, (SOCKADDR *)&addrClient, &len);
        //
    当客户端连接上来时, 拼接如下字符串       
        sprintf(sendBuf,
    "欢迎
    ip: %s 的用户连接, 这里是 Lellansin 的服务器\n"
    ,
    inet_ntoa(addrClient.sin_addr));
        //
    向客户端发送字符串
        send(sockClient,
    sendBuf,
    strlen(sendBuf)
    + 1, 0);
        //
    获取客户端返回的数据
        recv(sockClient,
    recvBuf, 100, 0);
        //
    打印客户端返回的数据
        printf("%s\n",
    recvBuf);
        //
    关闭socket
        closesocket(sockClient);
     
        getchar();
    }

    启动后防火墙有阻挡提示,这里接受就可以了。另外下图是原来博主测试时截的图,跟上面代码的输出部分稍稍有些区别。

    客户端(Client)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    #include
    <Winsock2.h>
    #include
    <stdio.h>
    #pragma
    comment(lib, "ws2_32.lib")
     
    void

    main()
    {
        int

    err;
        char

    *message;
        char

    recvBuf[100];
     
        SOCKET
    sockClient;
    //
    客户端 Scoket
        SOCKADDR_IN
    addrServer;
    //
    服务端地址
     
        WSADATA
    wsaData;
        WORD

    wVersionRequested;
     
        wVersionRequested
    = MAKEWORD( 2, 2 );
     
        err
    = WSAStartup( wVersionRequested, &wsaData );
     
        if

    ( err != 0 )
        {
            return;
        }
     
        if

    ( LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2 )
        {
            //
    启动错误,程序结束
            WSACleanup(
    );
            return;
        }
     
        //
    新建客户端 scoket
        sockClient
    = socket(AF_INET, SOCK_STREAM, 0);
     
        //
    定义要连接的服务端地址
        addrServer.sin_addr.S_un.S_addr
    = inet_addr(
    "127.0.0.1"); 
    //
    目标IP (127.0.0.1是本机地址)
        addrServer.sin_family
    = AF_INET;                          
    //
    协议类型是INET
        addrServer.sin_port
    = htons(6000);                        
    //
    连接端口1234
     
        //
    让 sockClient 连接到 服务端
        connect(sockClient,
    (SOCKADDR *)&addrServer,
    sizeof(SOCKADDR));
     
        //
    从服务端获取数据
        recv(sockClient,
    recvBuf, 100, 0);
     
        //
    打印数据
        printf("%s\n",
    recvBuf);
     
        message
    =
    "服务端你好~";
     
        //
    发送数据到服务端
        send(sockClient,
    message,
    strlen(message)
    + 1, 0);
     
        //
    关闭socket
        closesocket(sockClient);
        WSACleanup();
     
        getchar();
    //
    暂停
    }

    客户端与服务端更多通信,例子:《木马,你好!(二)最简单的木马》

    简单的端口扫描程序

    hostent结构体

    host entry的缩写,该结构记录主机的信息,包括主机名、别名、地址类型、地址长度和地址列表。之所以主机的地址是一个列表的形式,原因是当一个主机有多个网络接口时会有多个地址。

    1
    2
    3
    4
    5
    6
    7
    8
    struct

    hostent {
        char

    FAR * h_name;             
    /*
    主机正式名称 */
        char

    FAR * FAR * h_aliases;    
    /*
    主机别名 */
        short

    h_addrtype;              
    /*
    地址类型 */
        short

    h_length;                
    /*
    地址长度 */
        char

    FAR * FAR * h_addr_list;  
    /*
    主机网络地址指针 */
        #define
    h_addr h_addr_list[0]   /* 指向第一个地址 */
    };

    代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    #include
    <winsock2.h>
    #include
    <stdio.h>
    #include
    <stdlib.h>
    #pragma
    comment(lib,"ws2_32.lib")
     
    void

    Help(
    void

    );
     
    int

    main(
    int

    argc,
    char

    *argv[])
    {
        WORD

    wVersion = MAKEWORD(2, 0);
        WSADATA
    wsaData;
     
        //sockaddr_in结构体
        struct

    sockaddr_in
    sin;
     
        int

    iFromPort;
        int

    iToPort;
        int

    iNowPort;
        char

    *cHost;
     
        HOSTENT
    *host_entry;
        char

    *host_name;
        char

    host_address[256];
     
        SOCKET
    s;
     
        int

    iOpenPort = 0;
        int

    port[256], i;
     
        if

    (argc != 4)
        {
            Help();
            return

    -1;
        }
     
        iFromPort
    =
    atoi(argv[2]);
        iToPort
    =
    atoi(argv[3]);
        host_name
    = argv[1];
     
        if

    (iFromPort > iToPort || iFromPort < 0 || iFromPort > 65535 || iToPort < 0 || iToPort > 65535)
        {
            printf("起始端口不能大于结束端口,且范围为:1--65535
    "
    );
            return

    0;
        }
     
        if

    ( WSAStartup(wVersion , &wsaData) )
        {
            printf("初始化失败!");
            return

    -1;
        }
     
        //
    根据用户输入的域名来获取服务器主机信息
        host_entry
    = gethostbyname(host_name);
     
        if

    (host_entry != 0)
        {
            wsprintf(
    host_address,
    "%d.%d.%d.%d",
                (host_entry->h_addr_list[0][0]
    & 0x00ff),
                (host_entry->h_addr_list[0][1]
    & 0x00ff),
                (host_entry->h_addr_list[0][2]
    & 0x00ff),
                (host_entry->h_addr_list[0][3]
    & 0x00ff)
                );
            printf("\n主机名称:%s 
    主机地址:%s \n"
    ,
    host_name, host_address);
        }
     
        cHost
    = host_address;
     
        printf("=======
    开始扫描 ======= \n"
    );
     
        for

    (iNowPort = iFromPort; iNowPort <= iToPort; iNowPort++)
        {
            s
    = socket(AF_INET, SOCK_STREAM, 0);
            if

    (s == INVALID_SOCKET)
            {
                printf("create
    socket() failed!"
    );
                WSACleanup();
            }
     
            sin.sin_family
    = AF_INET;
            sin.sin_port
    = htons(iNowPort);
            sin.sin_addr.S_un.S_addr
    = inet_addr(cHost);
     
            if

    (connect(s, (
    struct

    sockaddr *)&
    sin,
    sizeof(sin))
    == SOCKET_ERROR)
            {
                printf("%s
    -> %d:未开放 \n"
    ,
    cHost, iNowPort);
                closesocket(s);
            }
            else
            {
                printf("%s
    -> %d:开放 \n"
    ,
    cHost, iNowPort);
                port[iOpenPort]
    = iNowPort;
                iOpenPort
    ++;
                closesocket(s);
            }
        }
     
        printf("=======
    扫描结果 ======= \n"
    );
        printf("主机:%s
    扫描到%d个端口,分别是: \n"
    ,
    host_name, iOpenPort);
     
        for

    ( i = 0; i < iOpenPort; i++)
        {
            printf("%d
    "
    ,
    port[i]);
        }
     
        //关闭socket
        closesocket(s);
        WSACleanup();
        return

    0;
    }
     
    //帮助函数
    void

    Help()
    {
        printf("Usage:
    \n"
    );
        printf("Port.exe
    <TargetIP> <BeginPort> <EndPort> \n"
    );
        printf("Example:
    \n"
    );
        printf("scan.exe
    127.0.0.1 100 200 "
    );
    }

    函数列表

    一、基本Socket函数

  • accept() 响应连接请求,返回一个连接socket,原来的socket返回监听状态
  • bind() 把一个socket绑定在某个端口上
  • CloseSocket() 关闭套接字
  • Connect() 连接
  • GetPeerName() 得到连接在指定套接口上的对等通信方的名字
  • GetSockName() 得到指定套接口上当前的名字
  • GetSockopt() 得到与制定套接口相关的属性选项
  • htonl() 把32位的数字从主机字节顺序转换到网络字节顺序
  • htons() 把16位的数字从主机字节顺序转换到网络字节顺序
  • inet_addr() 把一个Internet标准的点分十进制地址转换成Internet地址数值
  • inet_ntoa() 把Internet地址转换成点分十进制的字符串
  • ioctlsocket() 为套接字提供控制
  • listen() 监听套接字上连接请求的到来
  • ntohl() 把32位的数字从网咯字节顺序转换为主机字节顺序
  • ntons() 把16位的数字从网咯字节顺序转换为主机字节顺序
  • recv() 从已经连接的套接字接受数据
  • recvfrom() 从已连接的或没有连接的套接口接受数据
  • select() 执行同步IO多路复用
  • send() 从已连接的套几口发送数据
  • sendto() 从已连接的或没有连接的套接口发送数据
  • setsockopt() 设置与指定套接口相关的属性选项
  • shutdown() 关闭一部分全双工的链接
  • socket() 创建并返回一个socket

    二、获取信息

  • Gethostbyaddr() 根据网络地址得到对应的名字(会有多个)和地址
  • Gethostbyname() 根据主机名得到对应的名字(会有多个)和地址
  • gethostname() 得到本机主机名
  • getservbyname() 根据服务的名字得到对应的服务名和端口号
  • getservbyport() 根据端口号得到对应的服务名和端口号
  • getprotobyname() 根据协议名得到对应的协议名和数值
  • getprotobynumber() 根据端口号得到对应的协议名和数值

    三、DLL操作

  • WSAStartup 初始化底层的windows Sockets DLL
  • WSACleanup 从底层的Sockets DLL中撤销注册
  • WSAAsyncSelect Select函数的异步版本
  • WSAIsBlocking 确定底层的winsock DLL是否在该线程已经被一个调用阻塞
  • WSACancelBlockingCall 取消未完成的阻塞的API调用
  • WSASetBlockingHook 为底层的windows sockets实现设置阻塞钩子
  • WSASetLastError 设置下一次的WSAGetLastError返回的错误信息
  • WSAGetLastError 得到最近的一个windows sockets API调用错误的详细信息
  • WSAUnhookBlockingHook 恢复原始的阻塞钩子
  • WSACancelAsyncRequest 取消一个未完成的 WSAAsyncGetXByY 函数的实例

    文章索引

  • Windows API 教程(九) 网络编程的更多相关文章

    1. Windows API教程文件系统

      本篇文章主要介绍了"Windows API教程文件系统",主要涉及到Windows API教程文件系统方面的内容,对于Windows API教程文件系统感兴趣的同学可以参考一下. ...

    2. Java基础教程:网络编程

      Java基础教程:网络编程 基础 Socket与ServerSocket Socket又称"套接字",网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个s ...

    3. windows下的socket网络编程

      windows下的socket网络编程 windows下的socket网络编程 clinet.c 客户端 server.c 服务器端 UDP通信的实现 代码如下 已经很久没有在windows下编程了, ...

    4. windows下的socket网络编程(入门级)

      windows下的socket网络编程 clinet.c 客户端 server.c 服务器端 UDP通信的实现 代码如下 已经很久没有在windows下编程了,这次因为需要做一个跨平台的网络程序,就先 ...

    5. Java之旅_高级教程_网络编程

      摘自:http://www.runoob.com/java/java-networking.html JAVA网络编程 网络编程是指编写运行在多个设备(计算机)的程序,这些设备都通过网络连接起来. j ...

    6. Windows Embedded Compact 7网络编程概述(上)

      如今,不论是嵌入式设备.PDA还是智能手机,网络都是必不可少的模块.网络使人们更方便地共享设备上的信息和资源.而且,利用智能手机浏览互联网,也逐渐成为生活中的常见手段.物联网所倡导的物物相联,也离不开 ...

    7. Windows Embedded Compact 7网络编程概述(下)

      11.1.1 Select I/O模型 在Windows CE中,Select模型是唯一被支持的I/O模型.Select I/O模型就是利用select函数对I/O进行管理. 函数select的功能在 ...

    8. Windows API 教程(七) hook 钩子监听

      茵蒂克丝 如何创建一个窗口 手动创建窗口的流程 实际代码 安装钩子 (Install hook) 钩子简介 SetWindowsHookEx 函数 设置监听[键盘]消息 设置监听[鼠标]消息 如何创建 ...

    9. Java入门 - 高级教程 - 05.网络编程

      原文地址:http://www.work100.net/training/java-networking.html 更多教程:光束云 - 免费课程 网络编程 序号 文内章节 视频 1 概述 2 Soc ...

    10. C++使用Windows API CreateMutex函数多线程编程

      C++中也可以使用Windows 系统中对应的API函数进行多线程编程.使用CreateThread函数创建线程,并且可以通过CreateMutex创建一个互斥量实现线程间数据的同步: #includ ...

    随机推荐

    1. IDEA模板快捷键

      2.1 psvm:可生成 main 方法 2.2 sout:System.out.println() 快捷输出 类似的: soutp=System.out.println("方法形参名 = ...

    2. 力扣208——实现 Trie (前缀树)

      这道题主要是构造前缀树节点的数据结构,帮助解答问题. 原题 实现一个 Trie (前缀树),包含 insert, search, 和 startsWith 这三个操作. 示例: Trie trie = ...

    3. 《图解机器学习-杉山将著》读书笔记---CH5

      CH5 稀疏学习 重点提炼 提出稀疏学习的缘故: 虽然带有约束条件的最小二乘学习法结合交叉验证法,在实际应用中是非常有效的回归方法,但是,当参数特别多时,计算参数以及预测值需要大量时间.此时,我们要解 ...

    4. Spring Boot2 系列教程(三十一)Spring Boot 构建 RESTful 风格应用

      RESTful ,到现在相信已经没人不知道这个东西了吧!关于 RESTful 的概念,我这里就不做过多介绍了,传统的 Struts 对 RESTful 支持不够友好 ,但是 SpringMVC 对于 ...

    5. Tomcat的性能优化及JVM内存工作原理

      JVM性能优化原则:代码运算性能.内存回收.应用配置(影响Java程序主要原因是垃圾回收机制)代码层优化:避免过多循环嵌套.调用和复杂逻辑. Tomcat调优主要内容 1.增加最大连接数 2.调整工作 ...

    6. Redis系列之----Redis的两种持久化机制(RDB和AOF)

      Redis的两种持久化机制(RDB和AOF) 什么是持久化    Redis的数据是存储在内存中的,内存中的数据随着服务器的重启或者宕机便会不复存在,在生产环境,服务器宕机更是屡见不鲜,所以,我们希望 ...

    7. Java8 新特性(三) - 日期时间对象以及一些其他特性

      日期时间对象 关于日期时间的操作可以分为两种: 转换:与字符串的互相转换,与时间戳的互相转换 计算:计算两个时间点之间的间隔.时间点与时间段的计算(计算下周N.下个月D日.去年M月D日等等) Java ...

    8. Java单体应用 - 导读

      原文地址:http://www.work100.net/training/monolithic 更多教程:光束云 - 免费课程 Java单体应用 本阶段课程将学习如何进行Java单体Web应用开发,经 ...

    9. 国产CPU 申威1621 异数OS基础组件理论性能测试报告

      国产CPU 申威1621 异数OS基础组件理论性能测试报告 文章目录 国产CPU 申威1621 异数OS基础组件理论性能测试报告 前言 测试平台 测试项目 SW1621 异数OS 容器虚拟交换机模拟性 ...

    10. mybatis in查询

      原文地址:https://blog.csdn.net/u012427355/article/details/79580561 foreach的主要用在构建in条件中,它可以在SQL语句中进行迭代一个集 ...