2023年7月15日发(作者:)
WindowssocketC语⾔编程Windows socket C语⾔编程函数详解⽂章⽬录WSADATAWAS(Windows Sockets Asynchronous,Windows异步)⽤来存储被WSAStartup函数调⽤后返回的Windows Sockets数据。它包含执⾏的数据。typedef struct WSAData { WORD wVersion; //⾼位字节存储副版本号, 低位字节存储主版本号 WORD wHighVersion;//⽀持的Windows Sockets规范的最⾼版本#ifdef _WIN64 unsigned short iMaxSockets;//单个进程能够打开的socket的最⼤数⽬ unsigned short iMaxUdpDg; //能够发送或接收的最⼤的⽤户数据包协议(UDP)的数据包⼤⼩,以字节为单位 char FAR * lpVendorInfo; char szDescription[WSADESCRIPTION_LEN+1];//WinSockets实现的描述 char szSystemStatus[WSASYS_STATUS_LEN+1];//有关的状态或配置信息#else char szDescription[WSADESCRIPTION_LEN+1]; char szSystemStatus[WSASYS_STATUS_LEN+1]; unsigned short MaxSockets; unsigned short iMaxUdpDg; char FAR * lpVendorInfo;#endif} WSADATA;WSAStartupint WSAStartup ( WORD wVersionRequested, LPWSADATA lpWSAData );通过WSAStartup函数完成对Winsock服务的初始化,使⽤Socket之前必须调⽤WSAStartup函数wVersionRequested:指明程序请求使⽤的Socket版本。⼀个WORD(双字节)型数值,其中⾼位字节指明副版本、低位字节指明主版本lpWSAData 指向WSADATA数据结构的指针,⽤来返回请求的Socket的版本信息例如:if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0) /*MAKEWORD(2,2)表⽰使⽤WINSOCK2版本.wsd⽤来存储系统传回的关于WINSOCK的资料.*/{ cout << "WSAStartup Error = " << WSAGetLastError() << "n"; return;}MAKEWORD(): 创建⼀个⽆符号16位整型,通过连接两个给定的⽆符号参数WORD MAKEWORD(BYTE bLow, //指定新变量的低字节序BYTE bHigh //指定新变量的⾼字节序;);socketlpWSAData:指向WSADATA数据结构的指针,⽤来接收Windows Sockets 实现的细节socket#include#includeSOCKET socket(int af, int type, int protocol);af :为地址族(Address Family),也就是 IP 地址类型,常⽤的有 AF_INET 和 AF_INET6。INET是“Inetnet”的简写。AF_INET 表⽰ IPv4 地址; AF_INET6 表⽰ IPv6 地址,如 1110::A0B3:FA21:48AA:1A2B。type :为数据传输⽅式/套接字类型,常⽤的有 SOCK_STREAM(流格式套接字/⾯向连接的套接字) 和 SOCK_DGRAM(数据报套接字/⽆连接的套接字)protocol :表⽰传输协议,常⽤的有 IPPROTO_TCP (TCP 传输协议) 和 IPPTOTO_UDP(UDP 传输协议)。返回值:SOCKET 类型的句柄sockaddrstruct sockaddr{ unsigned short sa_family; //地址家族 AF char sa_data[14]; //14字节协议地址};当我们指定sa_family=AF_INET之后,sa_data的形式也就被固定了下来:最前端的2字节⽤于记录16位的端⼝,紧接着的4字节⽤于记录32位的IP地址,最后的8字节清空为零。sockaddr_instruct sockaddr_in{ unsigned short sin_family; //协议族 unsigned short sin_port; //存储端⼝号 struct in_addr sin_addr;//存储IP地址,使⽤in_addr这个数据结构 char sin_zero[8];//空字节};sin_zero: 让sockaddr与sockaddr_in两个数据结构保持⼤⼩相同⽽保留的空字节struct in_addr{ unsigned long s_addr;};inet_ptoninet_pton是⼀个IP地址转换函数,可以在将IP地址在 “点分⼗进制” 和 “⼆进制整数” 之间转换,⽽且inet_pton和inet_ntop这2个函数能够处理ipv4和ipv6。p和n分别代表表达(presentation)和数值(numeric)#include int inet_pton(int af, const char *src, void *dst);点分⼗进制-----数值格式af: 是地址簇src: 是来源地址dst: 接收转换后的数据。返回值: 若成功则为1,若输⼊不是有效的表达式则为0,若出错则为-1inet_ntop: 数值格式-----点分⼗进制const char *inet_ntop(int family, const void *addrptr, char *strptr, size_t len); //将数值格式转化为点分⼗进制的ip地址格式返回值: 若成功则为指向结构的指针,若出错则为NULLsetsockopt⽤于任意类型、任意状态的设置选项值。尽管在不同协议层上存在选项,但本函数仅定义了最⾼的“套接⼝”层次上的选项。int setsockopt(int sockfd, int level, int optname,const void *optval, socklen_t optlen);sockfd:将要被设置套接⼝的描述字。level: 选项所在的协议层。⽀持SOL_SOCKET、IPPROTO_TCP、IPPROTO_IP和IPPROTO_IPV6optname: 需要设置的选项名。optval: 指向存放选项待设置的新值的缓冲区。optlen: optval缓冲区长度返回值: 若⽆错误发⽣,setsockopt()返回0。 否则的话,返回SOCKET_ERROR错误,应⽤程序可通过 WSAGetLastError() 获取相应错误代码。错误代码:WSANOTINITIALISED:在使⽤此API之前应⾸先成功地调⽤WSAStartup()。WSAENETDOWN:套接⼝实现检测到⽹络⼦系统失效。WSAEFAULT:optval不是进程地址空间中的⼀个有效部分。WSAEINPROGRESS:⼀个阻塞的套接⼝调⽤正在运⾏中。WSAEINVAL:level值⾮法,或optval中的信息⾮法。WSAENETRESET:当SO_KEEPALIVE设置后连接超时。WSAENOPROTOOPT:未知或不⽀持选项。其中,SOCK_STREAM类型的套接⼝不⽀持SO_BROADCAST选项,SOCK_DGRAM类型的套接⼝不⽀持SO_DONTLINGER 、SO_KEEPALIVE、SO_LINGER和SO_OOBINLINE选项。WSAENOTCONN:当设置SO_KEEPALIVE后连接被复位。WSAENOTSOCK:描述字不是⼀个套接⼝。bind()将⼀本地地址与⼀套接⼝捆绑。本函数适⽤于未连接的数据报或流类套接⼝,在connect()或listen()调⽤前使⽤。当⽤socket()创建套接⼝后,它便存在于⼀个名字空间(地址族)中,但并未赋名。bind()函数通过给⼀个未命名套接⼝分配⼀个本地名字来为套接⼝建⽴本地捆绑(主机地址/端⼝号)。#include int PASCAL FAR bind( SOCKET sockaddr, const struct sockaddr FAR* my_addr,int addrlen);sockaddr: 标识⼀未捆绑套接⼝的描述字sockaddr: 赋予套接⼝的地址addrlen: my_addr的长度。返回值: 如⽆错误发⽣,则bind()返回0。否则的话,将返回-1,应⽤程序可通过WSAGetLastError()获取相应错误代码。connect()connect()⽤于建⽴与指定socket的连接。 int connect(SOCKET s, const struct sockaddr * name, int namelen);返回值: 成功则返回0, 失败返回-1,recvfrom从(已连接)套接⼝上接收数据,并捕获数据发送源的地址。ssize_t recvfrom (int sockfd, //已连接套接⼝的描述字 void *buf, //接收数据缓冲区 size_t len, //缓冲区长度 unsigned int flags, //调⽤操作⽅式 struct sockaddr *from, //指向装有源地址的缓冲区(可选) socket_t *fromlen); //指向from缓冲区长度值(可选)ssize_t 相当于 long intsocket_t 相当于int返回值: 正确接收返回接收到的字节数,失败返回-1.参数 flags: 以下⼀个或者多个标志的组合体,可通过“ | ”操作符连在⼀起 MSG_DONTWAIT:操作不会被阻塞。 MSG_ERRQUEUE: 指⽰应该从套接字的错误队列上接收错误值,依据不同的协议,错误值以某种辅佐性消息的⽅式传递进来,使⽤者应该提供⾜够⼤的缓冲区。导致错误的原封包通过msg_iovec作为⼀般的数据来传递。导致错误的数据报原⽬标地址作为msg_name被提供。错误以sock_extended_err结构形态被使⽤,定义如下 #define SO_EE_ORIGIN_NONE 0 #define SO_EE_ORIGIN_LOCAL 1 #define SO_EE_ORIGIN_ICMP 2 #define SO_EE_ORIGIN_ICMP6 3 MSG_PEEK:指⽰数据接收后,在接收队列中保留原数据,不将其删除,随后的读操作还可以接收相同的数据。 MSG_TRUNC:返回封包的实际长度,即使它⽐所提供的缓冲区更长, 只对packet套接字有效。sendto()指向⼀指定⽬的地发送数据,sendto()适⽤于发送未建⽴连接的UDP数据包 (参数SOCK_DGRAM)。int sendto( int s, //已建好连线的socket,利⽤UDP协议则不需经过连线操作 const void * msg, //数据内容 int len, //msg长度 unsigned int flags, //⼀般为0 const struct sockaddr * to, //sockaddr地址 int tolen //sockaddr的结构长度);
发布者:admin,转转请注明出处:http://www.yc00.com/web/1689409420a243423.html
评论列表(0条)