在 Winsocket 一:单线程阻塞server&client程序(tcp) 和 Winsocket 二:多线程阻塞服务器程序(tcp)介绍了阻塞tcp程序,阻塞式tcp程序服务器程序会因为建立连接和关闭连接而频繁的创建和关闭线程会产生大量的内存碎片,从而导致服务端程序不能保证长时间的稳定运行,本文简单介绍非阻塞式tcp程序的编写。
一、非阻塞
阻塞是指在进行一个操作的时候,如服务器接收客户端的连接(accept),客户端程序执行connect操作,服务器或者客户端读写数据(read、write),如果该操作没有执行完成(成功或者失败都算是执行完成),则程序会一直阻塞在操作执行的地方,直到该操作返回一个明确的结果。非阻塞式程序会在产生阻塞操作的地方阻塞一定的时间(该时间可以由程序员自己设置)。如果操作没有完成,在到达所设置的时间之后,无论该操作成功与否,都结束该操作而执行程序后面的操作。
二、非阻塞相关的系统函数
1、ioctlsocket()
为了执行非阻塞操作,需要在创建了一个套接口后,调用ioctlsocket函数将套接口设置为非阻塞的套接口:int ioctlsocket( SOCKET s, long cmd, u_long FAR *argp ),其作用是控制套接口的I/O模式。
s 要设置的套接口;
cmd 要对该套接口设置的命令,为了要将套接口设置成为非阻塞的,我们应该填写FIONBIO;
argp 设置为1表示非阻塞,0表示阻塞。
2、select()
为了进行非阻塞的操作,我们需要在进行非阻塞操作之前调用select函数:int select(int nfds, fd_set FAR *readfds, fd_set FAR *writefds, fd_set FAR *exceptfds, const struct timeval FAR *timeout ),其作用是设定一个或多个套接口的状态,并进行必要的等待,以便执行异步I/0(非阻塞)操作。