高级Socket编程
合集下载
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Fra Baidu bibliotek WSAAsyncSelect( )函数
int WSAAsyncSelect(SOCKET s, HWND Wnd,unsigned int wMsg, long lEvent); s:传入参数,标识一个需要事件通知的套接口描述符。
hWnd:传入参数,标识一个在网络事件发生时要想收到 消息的窗口或对话框的句柄。 wMsg:传入参数,在网络事件发生时要接收的消息,该 消息会投递到由hWnd句柄指定的窗口或对话框。 lEvent:传入参数,位屏蔽码,用于指明应用程序感兴 趣的网络事件集合。
基于阻塞模式多线程TCP文件服务器程序编程
• ①异步同步是指线程对数据获取的方式而言的, 异步:内核主动通知线程;同步:线程主动询问内核。 • ②而阻塞非阻塞是在线程主动询问内核时,内核对线程的不同处 理方式。所以阻塞非阻塞都是在同步的情况下发生的。 即 |----异步 |----同步|-----阻塞 |-----非阻塞
基于WSAEventSelect模型Socket编程
事件Select模型,它允许在多个套接字上接收以事件为基础 的网络事件通知。应用程序在创建套接字后,调用 WSAEventSelect()函数将事件对象与网络事件集合相关联。 当网络事件发生时,应用程序以事件的形式接收网络事件通 知。 WSAEventSelect模型与WSAAsyncSelect模型的区别: 网络事件发生时系统通知应用程序的方式不同。 WSAAsyncSelect模型以消息的形式通知应用程序; WSAEventSelect模型则以事件的形式进行通知。 Select模型是主动获取指定套接字的状态, WSAEventSelect模型和WSAAsyncSelect模型则是被动选 择系统通知应用程序套接字的状态变化。 WSAEventSelect模型每次只能等待64个事件。
事件对象状态置位—WSASetEvent( )
• 它将一个事件对象的状态从“nonsignaled”转 化为“signaled”。 BOOL WSASetEvent(WSAEVENT hEvent );
关闭事件对象—WSACloseEvent( )
创建一个事件对象并进行使用,当针对事件 对象的处理完成后,就应该释放此事件句 柄 所 占 用 的 资 源 , 通 过 调 用 WSACloseEvent( )函数来完成。
FIONREAD
SIOCATMAR K
异步与同步
异步I/O是内核帮你的线程盯着该线程所要的数据是否可用,而 线程可以去做别的事情。当数据可用时内核通知你的线程。需要 利用事件等机制来完成。 同步I/O是你的线程自己去向内核查询所要的数据是否可用。在 查询的时候,数据不可用的话: 1、如果内核将这个线程塞进等待队列,直到数据可用时,内核 将线程加进可运行队列,并将可用数据给它,则是阻塞型I/O ; 2、如果内核不将其塞进等待队列,而是直接给他一个error代码 表示数据不可用,则是非阻塞I/O 。执行非阻塞型I/O的线程需要 一遍一遍的去询问内核数据是否可用,否则它可能读不到可用的 数据。
非阻塞模式服务器应用程序编程实例
【例3.1】本实例中介绍的非阻塞模式服务器 应用程序启动时将在TCP端口9990上进行 监听。收到客户端应用程序发送来的数据 后,服务器应用程序将向客户端发送一个 表示收到数据的字符串。如果服务器收到 字符串“quit”,则退出应用程序。
非阻塞模式客户端应用程序编程实例
• 失败:返回0 • 注意:在可能的情况下,尽量然线程自行 退出!
网络服务器的设计模式
• 串行服务器
– 循环式 – 反应式 – 异步I/O
• 并发服务器
– 多进程 – 多线程
串行服务器方案
并发服务器方案
基于非阻塞模式的多线程服务器应用程序编程
• 主线程:负责接收来自客户端的连接请求,然后 创建专门与该客户端进行通信的线程。 • 专门的通信线程:
BOOL WSAResetEvent( WSAEVENT hEvent );
为 WSAEventSelect( ) 函 数 创 建 的 网 络 事 件 对 象 有 “signaled” 和“nonsignaled”两种工作状态 ,分别表示 “已置信”和“未置信”。 如果一个网络事件触发了与一个套接口关联在一起的事件 对象,则该对象的工作状态便会从“未置信”转变成“已 置信”。 在完成了一个I/O请求的处理之后,应用程序需要负责将 工作状态从“已置信”更改为“未置信”,完成该功能的 函数就是WSAResetEvent( )。
网络事件注册——WSAEventSelect( )
int WSAEventSelect ( SOCKET s, WSAEVENT hEventObject, long lNetworkEvents );
事件对象创建成功之后,就要将其与某个特定的套 接口关联在一起,要注册自己感兴趣的网络事件。
事件对象状态复位—WSAResetEvent( )
4个宏
FD_SET(s,*set):向set集合添加套接口描述符s。 FD_CLR(s,*set):从set集合中删除套接口描述字s。 FD_ISSET(s,*set):检查s是否为set集合中的一员,如果 是则返回“真”(TRUE)。 FD_ZERO(*set):将set集合初始化为空集。
Select模型应用举例
fd_set结构体
fd_set是一个结构类型说明符,代表着一系列特定套接口 的集合,它的定义如下: struct fd_set { u_int fd_count; /* how many are SET? */
SOCKET fd_array[FD_SETSIZE]; /* an array of SOCKETs */
进程和线程
线程 进程
进程和线程
• 进程(Process)是具有一定独立功能的程 序关于某个数据集合上的一次运行活动, 是系统进行资源分配和调度的一个独立单 位。 • 线程(Thread)是进程的一个实体,是 CPU调度和分派的基本单位。
CreateThread()
指向线程首地址的指针
• 创建线程
常用的网络事件
网络事件 FD_READ FD_WRITE FD_OOB FD_ACCEPT FD_CONNECT FD_CLOSE FD_QOS 含 义 应用程序想要接收读准备好的通知 应用程序想要接收写准备好的通知 应用程序想要接收带外数据到达的通 知 应用程序想要接收在套接口上将要连 接的通知 应用程序想要接收已连接好的通知 应用程序想要接收套接口关闭的通知 应用程序想要接收服务质量发生变化 的通知
• 成功:返回所创建线程的句柄 • 失败:返回NULL
创建线程
main() { ...; SOCKET s; ...; HANDLE th = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Thread, (LPVOID)&s, 0, NULL); ...; }
高级Socket编程
Socket编程模型
阻塞模式是指在指定套接字上调用函数执 行操作时,在没有完成操作之前,函数不 会立即返回。服务器程序在阻塞模式下调 用accept()函数. 默认创建的套接字为阻塞模式。 非阻塞模式是指在指定套接字上调用函数 执行操作时,无论操作是否完成,函数都 会立即返回。 在非阻塞模式下调用recv()函数时。
select( )函数
select( )函数的格式如下: int select( int nfds, fd_set FAR* readfds, fd_set FAR* writefds, fd_set FAR* exceptfds, const struct timeval FAR* timeout ); nfds:传入参数,本参数被忽略,仅起到与Berkeley API套接口兼容的作用。 readfds、writefds和exceptfds:这三个参数分别用于检 查可读性、可写性和例外数据。这三个参数既是传入参 数,也是传出参数。
} fd_set; fd_count表示套接口的数目; fd_array表示数组中存放的套接口号; FD_SETSIZE是常量,定义为64。
select( )函数使用说明
select( )函数可用于检查一个或多个套接口的状态。
对每一个套接口,调用者可查询它的可读性、可写性及错 误状态信息。 用fd_set结构来表示一组等待检查的套接口,在调用返回 时,这个结构存有满足一定条件的套接口组的子集。 select( )返回满足条件的套接口的数目。
WSAAsyncSelect模型举例
(a) UDP程序1的窗口 (b) UDP程序2的窗口 图10-1 UDP程序执行后的窗口
创建事件对象——WSACreateEvent( )
WSAEVENT WSACreateEvent( void );
调用该函数不需要传入参数。如果调用成功, 就是一个创建好的事件对象句柄;如果调 用失败,则返回WSA_INVALID_EVENT。
设置非阻塞模式套接字
• 调用ioctlsocket()函数将套接字设置为非阻塞模式: int ioctlsocket(SOCKET s, long cmd, u_long* argp);
cmd可选项 FIONBIO 说 明
参数argp指向一个无符号长整形数值。将argp设置为非0值,表示 启动Sockets的非阻塞模式;将argp设置为0值,表示禁用Sockets 的非阻塞模式; 确定套接口s自动读入的数据量。argp指向一个无符号长整型,其 中存有ioctlsocket()的返回值。如果s是SOCKET_STREAM类型, 则FIONREAD返回在一次recv()中所接收的所有数据量。这通常 与套接口中排队的数据总量相同。如果S是SOCK_DGRAM 型, 则FIONREAD返回套接口上排队的第一个数据报大小。 确实是否所有的带外数据都已被读入。这个命令仅适用于 SOCK_STREAM类型的套接口,且该套接口已被设置为可以在线 接收带外数据(SO_OOBINLINE)。
• P76
基于WSAAsyncSelect模型Socket编程
• WSAAsyncSelect模型又称为异步选择模型,它为每个 套接字绑定一个消息。当套接字上出现事先设置事件时, 操作系统会给应用程序发送这个消息,从而使应用程序 可以对该事件做相应的处理。
• WSAAsyncSelect模型的优点是在系统开销不大的情况 下可以同时处理许多个客户端连接。它的缺点是,即使 应用程序不需要窗口,也要至少设计一个窗口用于处理 套接字事件。而且,在一个窗口中处理大量的事件也可 能成为性能瓶颈。
DWORD WINAPI Thread(LPVOID lpParameter) { ...; SOCKET s = *((SOCKET *)lpParameter); ...; }
TerminateThread()
• 终止线程
– BOOL TerminateThread( – HANDLE hThread, – DWORD dwExitCode – );
Socket编程模型
• • • • 基于Select模型的Socket编程 基于WSAAsyncSelect模型的Socket编程 基于WSAEventSelect模型的Socket编程 基于重叠I/O模型的Socket编程
Select模型
• 选择模型,它可以使Windows Sockets应用 程序同时对多个套接字进行管理,调用 select()函数可以获取指定套接字的状态。 然后调用Windows Sockets API实现数据发 送和接收等操作。
– HANDLE CreateThread( – LPSECURITY_ATTRIBUTES lpThreadAttributes, – SIZE_T dwStackSize, – LPTHREAD_START_ROUTINE lpStartAddress, – LPVOID lpParameter, – DWORD dwCreationFlags, 传入线程的参数地址指针 – LPDWORD lpThreadId – );