Winsock API简介

本文介绍了Windows Sockets(WinSock2)的基本概念,包括面向连接的TCP通信和无连接的UDP通信,详细讲解了套接字选项和IO控制,并提供了流式套接字(TCP)编程的服务端与客户端设计示例。

Windows Sockets简介

Windows Sockets2是对1.1版本的一个扩展,通过WinSock2可以创建更高级的Internet、Intranet以及其
他网络应用程序,利用这些程序可以在不依赖所使用的网络协议的情况下在网络上传输应用数据;本文主要介绍
Winsock2的一些简单内容;

WinSock2简介

- 一个比较大的特点是,在WinSock2中,套接字句柄可以是文件句柄,这意味着我们可以将套接字句柄
-  用于Windows的I/O 接口,如ReadFile/WirteFile等;
- 可访问TCP/IP除外的其他协议(没用过...不了解)
- 协议独立的名字解析能力:包含了一套标准的API用于现存的大量名字解析域名系统,如DNS,SAP等
- (没用过...不了解)
- 还有好多其他扩展...就不一一列出了,有兴趣的可以参考《Windows网络编程完全讲义》

常用函数说明

面向连接的通信(TCP)

1.创建socket
原型:
///< af 指定套接字协议簇,IPv4协议簇改值为AF_INET,IPv6 该值为 AF_INET6
///< type 套接字类型 
///< protocol 指定上层(传输层)协议,TCP or UDP?
SOCKET socket(int af, int type, int protocol);
说明:成功则返回套接字描述符,否则返回INVALID_SOCKET
2.绑定套接字bind
原型:
///> s 尚未捆绑到具体地址的套接字
///> name 分配给套接字的地址,指向sockaddr结构的指针
///> namelen 长度,单位字节
int bind(SOCKET s, const struct sockaddr* name, int namelen);
说明:用于将本地协议地址与指定的套接字关联起来,即将套接字绑定到本地协议地址(协议地址:32位的IP和
16位的端口号的组合)
对于IPv4而言,name参数结构如下:
struct sockaddr_in {
    short sin_family; // 协议簇
    u_short sin_port; // 端口号
    struct in_addr sin_addr; // IP地址
    char sin_zero[8]; // 空字节
}
除了sin_family以外,该结构其他内容均以网络字节顺序存储(大端)
3.监听 listen
原型:
///> s 用于标识一个已经绑定但未连接的套接字
///> backlog 等待连接队列的最大长度
int listen(SOCKET s, int backlog);
说明:服务端一般调用bind以后,他就会紧跟着调用listen将套接字置于被动等待的模式以监听可能到来的连接
请求。当有连接到来时,可通过调用accept接受该请求;
为了管理所有到来的连接以及即将到来的连接,内核为每一个监听中的套接字维护两个队列:尚未完成连接队列和
已经完成连接队列;前者维护的是尚未完成三次握手的套接字,而后者维护的是已经完成连接的套接字;后边介绍
的accept接口实际就是从已经完成连接队列中去取出第一个然后返回的;
注意:只有**面向连接**的套接字才在**服务端**使用listen函数;
4.accept
原型:
///> s 处于监听状态的套接字描述符
///> addr 指向缓冲区的可选指针,用于接收为通信层所知的连接实体的地址,addr的实际格式取决于通信使用
     的地址簇协议
///> addrlen 可选指针
SOCKET accept(SOCKET s, struct sockaddr* addr, int* addrlen);
说明:当服务端处于监听状态,所有远端连接(connect)到来,accept接收到来的连接请求;
accept用于面向连接的套接字类型,如TCP.他从监听套接字完成三次握手的已经连接的队列中提取第一个连接,
接着他创建新的套接字并将其句柄作为accept的返回值,新建的套接字而非s才是实际连接的套接字;而原来处于
监听状态的套接字s仍处于监听状态,并等待其他新链接请求的到来;一定要区分这两个socket;
5.send
原型:
///> s 已经连接套接字描述符
///> buf 包含待发送数据的缓冲区
///> len 缓冲区buf中数据的长度,单位字节
///> flags 调用的执行方式
int send(SOCKET s, const char* buf, int len, int flags);
说明:对于UDP,需注意低层服务提供者支持的最大数据包大小;(没有很理解?是说UDP分包这块的工作要开发人
员来控制?一会学习下...)
6.recv
原型:
///> s 已经连接套接字描述符
///> buf 用于接收数据的缓冲区
///> len 缓冲区buf的长度,单位字节
///> flags 指定调用方式
int recv(SOCKET s, char* buf, int len, int flags);
说明:用于从已经连接的或者已经绑定的套接字上接收数据。即可用于UDP也可用于TCP;
对于面向连接的套接字或者无连接套接字,recv对可接收数据的地址有严格的限制:他仅从连接中指定的远程地址
接收数据,而来自其他地址的数据则被丢弃。对于TCP套接字,recv尽力返回当前所有的可用数据,最大可达缓冲
区的大小。而对于UDP套接字,recv将从由connection指定的目的地址中提取队列中的第一份数据报。如果数据
报大小超过指定的缓冲区的大小,他将使用与缓冲区大小相同的数据报前端部分填充缓冲区,同时返回响应错误
码,对于不可靠传输的UDP,其余数据将丢失;而对于可靠传输协议TCP,其余数据有服务提供者(是谁?)保留
至应用程序使用足够大的缓冲区调用recv。
7.connect
原型:
///> s 未连接的套接字描述符
///> name sockaddr 结构中的名字,他包含将要连接的远程主机的地址信息
///> namelen 名字长度,单位字节
int connect(SOCKET s, const struct sockaddr* name, int namelen);
说明:对于阻塞套接字,返回值直接就说明了连接成功与否;非阻塞套接字,若连接不能立即完成,则返回响应错
误码,可以使用select通过检查套接字的可写性来确定连接请求是否完成,writefds结合报告其成功结果,
exceptfds集合报告其失败结果;
对于已经建立的TCP连接(UDP无连接),他由一个套接字对唯一标识,而每个套接字由IP地址和端口
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值