⽹络编程(基于winsocket)--常⽤函数介绍(⼀)
本⽂主要记录⽹络编程中经常⽤到的函数,作为学习的笔记
1、winsocket地址结构
⼀般的sockaddr地址结构:
typedef struct sockaddr {
u_short sa_family;  //协议族
CHAR sa_data[14];    //IP地址和端⼝号
} SOCKADDR, *PSOCKADDR, FAR *LPSOCKADDR;
除了以上的不常⽤的地址结构外,还有⼀个常⽤的地址结构:
typedef struct in_addr {
write的返回值union {
struct { UCHAR s_b1, s_b2, s_b3, s_b4; } S_un_b;
struct { USHORT s_w1, s_w2; } S_un_w;
ULONG S_addr;
} S_un;
} IN_ADDR, *PIN_ADDR, FAR *LPIN_ADDR;
typedef struct sockaddr_in {
short  sin_family;    //协议族
u_short sin_port;      //端⼝号
IN_ADDR sin_addr;    //IP地址
CHAR sin_zero[8];    //填充数据
} SOCKADDR_IN, *PSOCKADDR_IN;
以上两种地址结构⽤法相似,作为相同;相⽐于sockaddr,sockaddr_in的数据段更为详细,可以使⽤sockaddr_in来初始化然后强制转化为sockaddr,然后将其作为套接字函数的参数。sockaddr_in为了保证与sockaddr相同的长度,还增加了8字节的填充数据。
此外winsocket还提供了对ipv6的⽀持。
typedef struct in6_addr {
union {
UCHAR      Byte[16];
USHORT      Word[8];
} u;
} IN6_ADDR, *PIN6_ADDR, FAR *LPIN6_ADDR;
typedef struct sockaddr_in6 {
ADDRESS_FAMILY sin6_family; // ipv6协议族
USHORT sin6_port;          // 端⼝号
ULONG  sin6_flowinfo;      // ipv6流信息
IN6_ADDR sin6_addr;        // ipv6地址
union {
ULONG sin6_scope_id;
SCOPE_ID sin6_scope_struct;
};
} SOCKADDR_IN6_LH, *PSOCKADDR_IN6_LH, FAR *LPSOCKADDR_IN6_LH;
除了以上地址类型外,winsocket2还增加了addrinfo结构⽤于描述地址信息,该结构在getaddrinfo函数中使⽤,以链表的形式保存地址信息
addrinfo结构的结构如下:
typedef struct addrinfo
{
int ai_flags;      // getaddrinfo函数的调⽤选项
int    ai_family;      // 地址族
int    ai_socktype;    // 套接字类型
int    ai_protocol;    // 协议
size_t    ai_addrlen;    // ai_addr指向的sockaddr结构缓冲区字节长度
char *    ai_canonname;  // 主机的正规名称
_Field_size_bytes_(ai_addrlen) struct sockaddr *  ai_addr;        // 以sockaddr结构描述的地址信息
struct addrinfo *  ai_next;        // 指向下⼀个addrinfo结构
}ADDRINFOA, *PADDRINFOA;
参数1(ai_flags):指定如何处理地址和名字,常见的参数值如下:
AI_PASSIVE                  0X00000001  // 套接字地址将⽤于监听绑定
AI_CANONNAME                0x00000002  // 返回⼀个规范名
AI_NUMERICHOST              0x00000004  // 以数字形式返回主机地址
AI_NUMERICSERV              0x00000008  // 以端⼝号返回服务
AI_ALL                      0x00000100  // 查IPv4和IPv6地址
AI_ADDRCONFIG              0x00000400  // 查询配置的地址类型(IPv4或是IPv6)
AI_V4MAPPED                0x00000800  // 如果没有到IPv6地址,则返回映射到IPv6格式的IPv4地址
参数2(ai_family):指定地址族,常见的地址族如下:
AF_INET          2            //IPv4:
AF_INET6        23            //IPv6
AF_UNSPEC        0            //协议⽆关
参数3(ai_socktype):指明套接字的类型,套接字类型如下:
SOCK_STREAM    1              /* 流式套接字 (TCP)*/
SOCK_DGRAM      2              /* 数据包套接字(UDP)*/
SOCK_RAW        3              /* 原始套接字 */
SOCK_RDM        4              /* 可靠传输套接字*/
SOCK_SEQPACKET  5              /* 在UDP的基础上提供伪数据包 *
参数4(ai_protocol):指明传输协议,该参数取决于af、type参数类型
IPPROTO_TCP  //TCP协议,使⽤条件:af是AF_INET or AF_INET6;type是SOCK_STREAM
IPPROTO_UDP  //UDP协议,使⽤条件:af是AF_INET or AF_INET6;type是SOCK_DGRAM)
IPPROTO_RM  //PGM(Pragmatic General Multicast,实际通⽤组播协议)协议,使⽤条件,af是AF_INET 、type是SOCK_RDM
参数5(ai_addrlen):指定addrinfo结构的长度
参数6 (ai_canonname):主机的规范名称
参数7 (ai_addr):指向sockaddr结构
指向 sockaddr 结构的指针。每个返回的addrinfo结构中的ai_addr成员指向⼀个填充的套接字地址结构。
参数8 (ai_next):指向下⼀个addrinfo结构
addrinfo结构主要⽤于getaddrinfo()中,getaddrinfo函数提供了⼀种与协议⽆关的地址获取和表⽰⽅式,通过getaddrinfo获取到的addrinfo结构中的内容都是以⽹络字节顺序表⽰。
INT
WSAAPI
getaddrinfo(
_In_opt_        PCSTR              pNodeName,
_In_opt_        PCSTR              pServiceName,
_In_opt_        const ADDRINFOA *  pHints,
_Outptr_        PADDRINFOA *        ppResult
);
参数1:点分⼗进制形式的IP地址字符串,const char *
参数2:端⼝号或是服务名称,http、ftp,const char*
参数3:指向addrinfo结构的指针
参数4:返回⼀个指向addrinfo结构体链表的指针
返回值:0,成功;⾮0,失败;
2、地址转换
利⽤inet_addr()函数将点分⼗进制地址转换为⽆符号4字节的整数地址
失败返回INADDR_NONE,证明是⼀个⾮法地址。
利⽤inet_ntoa()函数将整数性抵制装换为点分⼗进地址
在80x86的架构下,inet_addr()函数按照⼤端模式读取内存中的四字节的IP地址,同样inet_ntoa()函数按照⼩段模式读取内存中四字节的IP地址。
3、⽹络字节和主机字节的转换
htonl():将主机字节顺序从u_long转换为⽹络字节
htons():将主机字节顺序从u_short转换为⽹络字节
ntohl():将u_long从⽹络字节转换为主机字节
ntohs():将u_short从⽹络字节转换为主机字节
4、流式(TCP)套接字交互模型
5、函数介绍
(1)WSAStartup():初始化函数
int WSAStartup(
_In_ WORD wVersionRequested,  //双字节版本号,低字节为主版本号,⾼字节为修订版本号
_Out_ LPWSADATA lpWSAData      //<span ><span >指向wasdata数据结构的指针,⼀);
编程⽰例:

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。