WinSock编程基础

本文介绍了Windows下的网络编程接口WinSock的基本使用方法,包括WinSock2.2的应用程序框架搭建,WSAStartup函数的初始化过程,以及IP地址在网络通信中的表示形式与转换。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Winsock是Windows下的网络编程接口,在VS中可以使用WinSock API开发网络应用程序,实现计算机之间的通信。

构建WinSock应用程序框架

WinSock包含两个主要的版本,WinSock1和WinSock2。使用WinSock1时需要导入头文件winscok.h和winsok32.lib,使用WinSock2时,需要导入winsock2.h和ws2_32lib.
下面是WinSock2.2实现网络通信的应用程序框架:

#include <WinSock2.h>
#pragma comment(lib,"WS2_32.lib")

int _tmain(int argc,_TCHAR* argv[])
{
    //初始化WindowsSocket
    WSADATA wsdData;

    //初始化Socket动态库
    if(WSAStartup(MAKEWORD(2,2),&wsdData)!=0){
        printf("WSAStartup Failed!\n");
        return -1;
    }
    //使用WinSock实现网络通信
    //......

    //释放socket
    if(SOCKET_ERROR == WSACleanup())
        printf("WSACleanup failed!\n");
    return 0;
}

结构体WSADATA用来存储调用WSAStartup()后返回的Windows Socket数据。定义如下:

typedef struct WSAData {
        WORD                    wVersion;
        WORD                    wHighVersion;
#ifdef _WIN64
        unsigned short          iMaxSockets;
        unsigned short          iMaxUdpDg;
        char FAR *              lpVendorInfo;
        char                    szDescription[WSADESCRIPTION_LEN+1];
        char                    szSystemStatus[WSASYS_STATUS_LEN+1];
#else
        char                    szDescription[WSADESCRIPTION_LEN+1];
        char                    szSystemStatus[WSASYS_STATUS_LEN+1];
        unsigned short          iMaxSockets;
        unsigned short          iMaxUdpDg;
        char FAR *              lpVendorInfo;
#endif
} WSADATA, FAR * LPWSADATA;

WSAStartup()函数用于初始化Windows Sockets,并返回WSADATA结构体。只有调用了这个函数后,才能调用其他Windows Sockets API函数,实现网络通信。WSAStartup()原型如下:

int WSAStartup(
    __in WORD wVersionRequested,    /*WinSock版本*/
    __out LPWSADATA lpWSAData    /*指向WSADATA结构体的指针*/
    );

IP地址的表现形式

对于网络管理员或者普通用户,IP地址通常用点分十进制表示。但是计算机中,为了不浪费存储空间,使用无符号长整数来存储和表示IP地址,而且分为网络字节顺序(Network Byte Order,NBO)和主机字节顺序(Host Byte Order,HBO)。TCP/IP规定,在低位存储地址中保存数据的高位字节,这种存储方式被称为网络字节顺序。不同类型,不同操作系统的设备在发送数据前必须将二进制数据转换为网络字节顺序。
C++中采用in_addr来保存网络字节顺序格式的IP地址,它的定义代码如下:

typedef struct in_addr {
        union {
                struct { UCHAR s_b1,s_b2,s_b3,s_b4; } S_un_b;    /*由4个u_char变量组成的主机格式IP地址*/
                struct { USHORT s_w1,s_w2; } S_un_w;    /*由2个u_short变量组成的主机格式IP地址*/
                ULONG S_addr;    /*由u_long变量表示的主机格式IP地址*/
        } S_un;

使用inet_addr()和inet_ntoa()两个函数可实现点分法IP地址字符串和网络字节字符顺序格式IP地址的转换。
inet_addr():将点分法IP转换为in_addr结构体中的IP地址格式,原型:

unsign long inet_addr(
    const char FAR * cp
    );

inet_addr():将in_addr结构体中的IP地址格式转换为点分法IP,原型:

char FAR* inet_ntoa(
    __in struct in_addr in
    );

主机字节顺序格式

不同主机对IP地址进行存储时使用的格式也不同。有的和网络字节顺序相同,有的与网络字节顺序相反。Intel x86系列主机字节顺序刚好与网络字节顺序相反。
可以使用htonl()、htons()、ntohl()、ntohs()四个函数实现主机字节顺序和网络字节顺序格式之间的转换。
u_long格式的主机字节转网络字节:

u_long htonl(
    u_long hostlong
    );

u_short格式的主机字节转网络字节:

u_short htons(
    u_short hostshort
    );

u_long格式的网络字节转主机字节:

u_long ntohl(
    u_long netlong
    );

u_short格式的网络字节转主机字节:

u_short ntohs(
    u_short netshort
    );
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值