总结
来源:互联网 发布:淘宝虾米vip兑换码在哪 编辑:程序博客网 时间:2024/06/10 20:22
select模型
select(
int nfds;
fd_set fdread,
fd_set fdWrite,
fd_set fdException,
timeval time
)
FD_ZERO(*set) 将set初始化成空集合,集合在使用前都要清空
FD_CLR(s,*set) 从set中删除套接字S
FD_ISET(s,*set) 检查s是否为set集合
FD_SET(s,*set) 将套接字s加入set集合
select的优势是在单个线程中处理多个套接字,但是最大限制是64,由
FD_SETSIZE 定义,若要重新定义则需要在winsock2.h前定义.
WSAAsyncSelect 异步模型,提供异步通知,但是不提供异步数据传送
异步消息通知,自动置为非阻塞.
int WSAAsyncSelect(
SOCKET s, // 套接字
HWND hwnd, // 窗口句柄
unsigned int wMsg, // 自定义消息,标识发生了网络事件
long lEvent, // 要监听的事件,如果是0,则代表着清除网络事件
)
closesocket也可以清除套接字上的事件
对于消息中的 wParam : 表示套接字
对于消息中的 lParam :低位字表示网络事件
高字代表着可能出现的错误代码
这里可以用WSAGETSELECTERROR获得高字位包含的错误信息
我们可以用WSAGETSELECTEVENT获得发生了哪些事件
一般是先调用WSAGETSELECTERROR,检查错误,如果没有错误再
查看发生了什么事件.
事件模型
WSAEventSelect模型,提供异步通知,但是不提供异步数据传送
1. WSAEVENT WSACreateEvent(void);
其返回值是人工重设的事件句柄
2. int WSAEventSelect(
SOCKET s.
WSAEVENT hEventObject,
long LNetWorkEvents,//感兴趣的事件
);
该步骤将事件句柄和套接字关联起来
才创建完毕时未传信状态,且是人工重设
WSAResetEvent(hEvent)重置信号状态,即变为未传信状态
WSACloseEvent(hEvent)关闭时间句柄
检测事件发生的函数
DWORD WSAWaitForMultipleEvents(
DWORD CEvent, // 时间句柄数量
const WSAEVENT FAR* lpEvents, // 要监听的事件句柄集合
DWORD fWaitAll, //是否等待全部事件句柄都有信号,才返回,false表示只要有信号传递,就返回
DWORD dwTimeout,
)
当调用返回时,返回的是发生了的信号在lpEvents中的位置.
这个时候就可以调用WSAEbumNetworkEvents(...) 函数枚举网络事件类型,
并且还有将指定事件句柄重置为未传信的功能.
WSAEnumNetworkEvents(
SOCKET s,
WSAEVENT hEventObject,
LPWSANETWORKEVENTS lpNetworkEvents
) ;
也可以使用wsaresetevent复位
typedef struct _WSANETWORKEVENT
{
long lNetorkEvents; // 网络事件类型
int i ErrorCode[FD_MAX_EVENT]; // 错误码
}
一个传信状态的事件句柄,可能发生多个网络事件
example:
if(NetworkEvents.lNetorkEvents & FD_READ)
{
if(NetworkEvents.iErrorCode[FD_READ_BIT] != 0)
{
// 发生了错误
}
}
重叠模型 (Overlapped IO)
typedef struct _WSAOVERLAPPED {
DWORD Internal;
DWORD InternalHigh;
DWORD Offset;
DWORD OffsetHigh;
WSAEVENT hEvent;
} WSAOVERLAPPED, *LPWSAOVERLAPPED;
其中,只需要设置事件句柄就可以了
其余的由系统帮助设定,
然后调用事件模型上的函数就可以判断了发生了哪些事件
最后调用WSAGetOverlappedResult(
SOCKET s, // 与重叠操作相对应的套接字
LPWSAOVERLAPPED lpOverlapped, // 与套接字相对应的重叠结构体
LPDWORD[out] lpcbTransfer, // 返回实际读或者写的字节
BOOL fWait, // 是否等待操作完成
LPDWORD lpdwFlags // 标志着错误.
);
BOOL WSAAPI WSAGetOverlappedResult(
_In_ SOCKET s,
_In_ LPWSAOVERLAPPED lpOverlapped,
_Out_ LPDWORD lpcbTransfer,
_In_ BOOL fWait,
_Out_ LPDWORD lpdwFlags
);
完成例程
该模型时另一种管理重叠IO的模型,一个完成历程必须得拥有下述函数
原形
void CALLBACK CompletionROUTINE(
DWORD dwError, //表名一个重叠操作的完成状态是什么
DWORD cbTransferred, // 表名了在重叠操作期间,实际传输的字节量是多大
LPWSAOVERLAPPED lpOverlapped, // 表名了当初出啊你的WSAOVERLAPPED结构
DWORD dwFlags // 表明发挥操作结束时可能用的标志(如从WSARecv)
);
首先在使用这种模型之前,需要创建一个完成端口
HANDLE CreateIoCompletionPort
(
HANDLE FileHandle,
HANDLE ExistingCompletionPort,
DWORD CompletionKey,
DWORD NumberOfConcurrentThreads // 该完成端口上运行执行的线程数量,为0时则告诉处理器,有多少个处理器就运行多少个线程
);
eg: CompletionPort = CreateIoCompletionPort(
INVALID_HANDLE_VALUE,
NULL,
0,0
);
select(
int nfds;
fd_set fdread,
fd_set fdWrite,
fd_set fdException,
timeval time
)
FD_ZERO(*set) 将set初始化成空集合,集合在使用前都要清空
FD_CLR(s,*set) 从set中删除套接字S
FD_ISET(s,*set) 检查s是否为set集合
FD_SET(s,*set) 将套接字s加入set集合
select的优势是在单个线程中处理多个套接字,但是最大限制是64,由
FD_SETSIZE 定义,若要重新定义则需要在winsock2.h前定义.
WSAAsyncSelect 异步模型,提供异步通知,但是不提供异步数据传送
异步消息通知,自动置为非阻塞.
int WSAAsyncSelect(
SOCKET s, // 套接字
HWND hwnd, // 窗口句柄
unsigned int wMsg, // 自定义消息,标识发生了网络事件
long lEvent, // 要监听的事件,如果是0,则代表着清除网络事件
)
closesocket也可以清除套接字上的事件
对于消息中的 wParam : 表示套接字
对于消息中的 lParam :低位字表示网络事件
高字代表着可能出现的错误代码
这里可以用WSAGETSELECTERROR获得高字位包含的错误信息
我们可以用WSAGETSELECTEVENT获得发生了哪些事件
一般是先调用WSAGETSELECTERROR,检查错误,如果没有错误再
查看发生了什么事件.
事件模型
WSAEventSelect模型,提供异步通知,但是不提供异步数据传送
1. WSAEVENT WSACreateEvent(void);
其返回值是人工重设的事件句柄
2. int WSAEventSelect(
SOCKET s.
WSAEVENT hEventObject,
long LNetWorkEvents,//感兴趣的事件
);
该步骤将事件句柄和套接字关联起来
才创建完毕时未传信状态,且是人工重设
WSAResetEvent(hEvent)重置信号状态,即变为未传信状态
WSACloseEvent(hEvent)关闭时间句柄
检测事件发生的函数
DWORD WSAWaitForMultipleEvents(
DWORD CEvent, // 时间句柄数量
const WSAEVENT FAR* lpEvents, // 要监听的事件句柄集合
DWORD fWaitAll, //是否等待全部事件句柄都有信号,才返回,false表示只要有信号传递,就返回
DWORD dwTimeout,
)
当调用返回时,返回的是发生了的信号在lpEvents中的位置.
这个时候就可以调用WSAEbumNetworkEvents(...) 函数枚举网络事件类型,
并且还有将指定事件句柄重置为未传信的功能.
WSAEnumNetworkEvents(
SOCKET s,
WSAEVENT hEventObject,
LPWSANETWORKEVENTS lpNetworkEvents
) ;
也可以使用wsaresetevent复位
typedef struct _WSANETWORKEVENT
{
long lNetorkEvents; // 网络事件类型
int i ErrorCode[FD_MAX_EVENT]; // 错误码
}
一个传信状态的事件句柄,可能发生多个网络事件
example:
if(NetworkEvents.lNetorkEvents & FD_READ)
{
if(NetworkEvents.iErrorCode[FD_READ_BIT] != 0)
{
// 发生了错误
}
}
重叠模型 (Overlapped IO)
typedef struct _WSAOVERLAPPED {
DWORD Internal;
DWORD InternalHigh;
DWORD Offset;
DWORD OffsetHigh;
WSAEVENT hEvent;
} WSAOVERLAPPED, *LPWSAOVERLAPPED;
其中,只需要设置事件句柄就可以了
其余的由系统帮助设定,
然后调用事件模型上的函数就可以判断了发生了哪些事件
最后调用WSAGetOverlappedResult(
SOCKET s, // 与重叠操作相对应的套接字
LPWSAOVERLAPPED lpOverlapped, // 与套接字相对应的重叠结构体
LPDWORD[out] lpcbTransfer, // 返回实际读或者写的字节
BOOL fWait, // 是否等待操作完成
LPDWORD lpdwFlags // 标志着错误.
);
BOOL WSAAPI WSAGetOverlappedResult(
_In_ SOCKET s,
_In_ LPWSAOVERLAPPED lpOverlapped,
_Out_ LPDWORD lpcbTransfer,
_In_ BOOL fWait,
_Out_ LPDWORD lpdwFlags
);
完成例程
该模型时另一种管理重叠IO的模型,一个完成历程必须得拥有下述函数
原形
void CALLBACK CompletionROUTINE(
DWORD dwError, //表名一个重叠操作的完成状态是什么
DWORD cbTransferred, // 表名了在重叠操作期间,实际传输的字节量是多大
LPWSAOVERLAPPED lpOverlapped, // 表名了当初出啊你的WSAOVERLAPPED结构
DWORD dwFlags // 表明发挥操作结束时可能用的标志(如从WSARecv)
);
首先在使用这种模型之前,需要创建一个完成端口
HANDLE CreateIoCompletionPort
(
HANDLE FileHandle,
HANDLE ExistingCompletionPort,
DWORD CompletionKey,
DWORD NumberOfConcurrentThreads // 该完成端口上运行执行的线程数量,为0时则告诉处理器,有多少个处理器就运行多少个线程
);
eg: CompletionPort = CreateIoCompletionPort(
INVALID_HANDLE_VALUE,
NULL,
0,0
);
0 0
- 总结
- 总结
- 总结
- 总结
- 总结!
- 总结
- 总结.
- 总结。
- 总结
- 总结
- 总结
- 总结
- 总结
- 总结
- 总结
- 总结
- 总结
- 总结
- C#里为什么static virtual不能同时使用
- api-ms-win-crt-runtime-l1-1-0.dll丢失的问题
- Android 网络编程之同步,异步,阻塞和非阻塞
- 基于ffmpeg的开源项目havlena,源码修改系列一之 修复bug
- 静态方法和单件模式具体区别在哪里?
- 总结
- gprof 使用和介绍
- 35. Search Insert Position
- 快递100 快递公司编码-标准国际
- Ajax简介
- Eclipse之常用设置
- Jetty Cross Origin Filter解决jQuery Ajax跨域访问的方法
- windows下网络事件的类型
- 原创SpringMvc+Mybatis+Redis框架