Windows Socket编程TCP范例之三(WSAAsyncSelect)
来源:互联网 发布:数学排列组合公式算法 编辑:程序博客网 时间:2024/06/03 09:25
WSAAsyncSelect模型允许应用程序以Windows消息的形式接收网络事件通知.这个模型是为了适应Windows的消息驱动环境而设置的,现在许多对性能要求不高的网络应用程序都采用WSAAsyncSelect模型.MFC中的CSocket类也使用了它.
示例图片:------------------------------------------------------------------------------------------------
以下示例还是实现和前两篇文章(之一&之二)一样的功能:Client端连接Server端,向Server端发送数据。Server端接受Client端发送过来的数据并输出。Server端还是单线程处理多Client端连接的情况。
Server.cpp-----------------------------------------------------------------------------------------
1、在main中创建窗口但不调用ShowWindow即隐藏了窗口。由于是控制函程序,所以还是有控制函窗口的。
2、在ServerSocketProc中去初始化Windows Socket库、创建Socket、绑定Socket、监听Socket。
3、在窗口函数中处理Socket相关的消息
4、Client端通过closesocket关闭套接字会进入到以下的FD_CLOSE事件输出:"FD_CLOSE"
而直接关闭Client端会使WSAGETSELECTERROR(lParam)为真,也就会输出:"WSAGETSELECTERROR get error"
#include <windows.h>#include <iostream>using namespace std;LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);int ServerSocketProc(HWND);#pragma comment(lib, "Ws2_32.lib") #define WM_SOCKET WM_USER + 100#define PORT_NO 6000 #define BACKLOG 10 // 全局变量SOCKET gSockSrv;int main(){static TCHAR lpszAppName[] = TEXT("TestWin");HWND hwnd;MSG msg;WNDCLASS wc;wc.style = CS_HREDRAW | CS_VREDRAW;wc.lpfnWndProc = WndProc;wc.cbClsExtra = 0;wc.cbWndExtra = 0;wc.hInstance = NULL;wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);wc.hCursor = LoadCursor(NULL, IDC_ARROW);wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);wc.lpszMenuName = NULL;wc.lpszClassName = lpszAppName;// 注册窗口类if (!RegisterClass(&wc)){MessageBox(NULL, TEXT("This program requires Windows NT!"),lpszAppName, MB_ICONERROR);return 0;}// 创建应用程序主窗口hwnd = CreateWindow(lpszAppName,TEXT("Server"),WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,NULL,NULL);if (NULL == hwnd){MessageBox(NULL, TEXT("CreateWindow failed."),lpszAppName, MB_ICONERROR);return 0;}// 创建Socket服务int ret = ServerSocketProc(hwnd);if (0 != ret){MessageBox(NULL, TEXT("ServerSocketProc failed."),lpszAppName, MB_ICONERROR);return 0;}// 消息循环 while (GetMessage(&msg, NULL, 0, 0)){TranslateMessage(&msg);DispatchMessage(&msg);} // 清理资源------ closesocket(gSockSrv); WSACleanup();return msg.wParam;}//// 窗口过程函数//LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){switch (message){case WM_SOCKET: // 处理Socket信息{int ret;SOCKET sock = wParam;// 查看是否出错if(WSAGETSELECTERROR(lParam)){closesocket(sock);cout << "WSAGETSELECTERROR get error" << endl;if (sock == gSockSrv){DestroyWindow(hwnd);}return 0;}// 处理发生的事件switch(WSAGETSELECTEVENT(lParam)){case FD_ACCEPT:// 监听中的套接字检测到有连接进入{int len=sizeof(SOCKADDR);SOCKADDR_IN addrClient;SOCKET sockConn = accept(sock, (SOCKADDR*)&addrClient, &len);if (INVALID_SOCKET == sockConn) { cout << "accept() failed:" << WSAGetLastError() << endl; return 0; } cout << "接受到新连接:" << inet_ntoa(addrClient.sin_addr) << endl;WSAAsyncSelect(sockConn, hwnd, WM_SOCKET, FD_READ | FD_WRITE | FD_CLOSE);}break;case FD_WRITE:{}break;case FD_READ:{char recvBuffer[MAX_PATH] = {0}; ret = recv(sock, recvBuffer, sizeof(recvBuffer), 0);if (ret == 0) { cout << "Connection has been gracefully closed." << endl; closesocket(sock); return 0; } else if (ret == SOCKET_ERROR) { cout << "Connection has been closed ungracefully." << endl; closesocket(sock); return 0; } cout << "Receive Data from Client:" << recvBuffer << endl; }break;case FD_CLOSE:{ cout << "FD_CLOSE" << endl;closesocket(sock);}break;}}break;case WM_DESTROY:PostQuitMessage(0);return 0;}return DefWindowProc(hwnd, message, wParam, lParam);}int ServerSocketProc(HWND hwnd){cout << "ServerSocketProc-----------------------------------------BEG" << endl;WSADATA wsaData;int ret;WORD wVersionRequested = MAKEWORD(2, 2);SOCKET sockSrv;SOCKADDR_IN addrSrv;HANDLE hThread = NULL;// 初始化Windows Socket------ret = WSAStartup(wVersionRequested, &wsaData);if (ret != 0) {cout << "WSAStartup() failed:" << WSAGetLastError() << endl;return -1;}// 创建Socket------sockSrv = socket(AF_INET, SOCK_STREAM, 0);if (INVALID_SOCKET == sockSrv){cout << "socket() failed:" << WSAGetLastError() << endl;WSACleanup();return -1;}gSockSrv = sockSrv;addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);addrSrv.sin_family = AF_INET;addrSrv.sin_port = htons(PORT_NO);// Bind Socket------ret = bind(sockSrv, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));if (SOCKET_ERROR == ret){cout << "bind() failed:" << WSAGetLastError() << endl;closesocket(sockSrv);WSACleanup();return -1;}// 监听------ret = listen(sockSrv, BACKLOG);if (SOCKET_ERROR == ret){cout << "listen() failed:" << WSAGetLastError() << endl;closesocket(sockSrv);WSACleanup();return -1;}// WSAAsyncSelect------WSAAsyncSelect(sockSrv, hwnd, WM_SOCKET, FD_ACCEPT | FD_CLOSE); cout << "ServerSocketProc-----------------------------------------END" << endl;cout<< "Server started......" << endl;return 0;}
#include <iostream>#include <windows.h>using namespace std;#pragma comment(lib, "Ws2_32.lib")#define PORT_NO 6000#define SRV_IP_ADDR "127.0.0.1"int main(int argc, char* argv[]){int ret;WSADATA wsaData;WORD wVersionRequested = MAKEWORD(2, 2);SOCKET sockClient;SOCKADDR_IN addrSrv;// 初始化Windows Socket------ret = WSAStartup(wVersionRequested, &wsaData);if (ret != 0) {cout << "WSAStartup() failed:" << WSAGetLastError() << endl;return -1;} // 创建Socket------sockClient = socket(AF_INET, SOCK_STREAM, 0);if (INVALID_SOCKET == sockClient){cout << "socket() failed:" << WSAGetLastError() << endl;WSACleanup();return -1;}addrSrv.sin_addr.S_un.S_addr = inet_addr(SRV_IP_ADDR);addrSrv.sin_family = AF_INET;addrSrv.sin_port = htons(PORT_NO);// 连接------ret = connect(sockClient, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));if (SOCKET_ERROR == ret){cout << "connect() failed:" << WSAGetLastError() << endl;closesocket(sockClient);WSACleanup();return -1;}else{cout << "connect() successfully." << endl;}// 发送数据------char sendBuf[MAX_PATH] = {0};while (1){cin.getline(sendBuf, sizeof(sendBuf));if (strcmp(sendBuf, "exit") == 0){break;}ret = send(sockClient, sendBuf, strlen(sendBuf)+1, 0);if (SOCKET_ERROR == ret){cout << "send() failed:" << WSAGetLastError() << endl;closesocket(sockClient);WSACleanup();return -1;}}// 清理资源-------closesocket(sockClient);WSACleanup();cout << "exit..." << endl;return 0;}
示例图片:------------------------------------------------------------------------------------------------
- Windows Socket编程TCP范例之三(WSAAsyncSelect)
- Windows Socket编程TCP范例
- Windows Socket编程TCP范例之二(select)
- Windows Socket编程TCP范例之四(WSAEventSelect)
- Windows socket 之WSAAsyncSelect模型
- Windows socket 之WSAAsyncSelect模型
- Windows socket 之WSAAsyncSelect模型
- Windows socket 之WSAAsyncSelect模型
- Windows socket 之WSAAsyncSelect模型
- Socket网络编程之WSAAsyncSelect模型
- Windows Socket I/O模型之 WSAAsyncSelect模式
- Winsock 网络编程 Socket模型之WSAAsyncSelect模型
- windows sockets之WSAAsyncSelect
- VS2012之MFC带Windows socket下的阻塞式TCP范例
- socket编程之tcp
- Socket编程之TCP
- C++ Socket TCP范例
- windows socket 编程实例--TCP
- android中scrollview与listview共存
- 游走Android系列之Service
- 在.NET使用JSON作为数据交换格式
- 单例模式的4种写法
- 银行业务调度系统
- Windows Socket编程TCP范例之三(WSAAsyncSelect)
- 在64位操作系统上运行32位的程序
- 模运算------x的y次方再模n
- Eclipse 问题:java.lang.ClassNotFoundException: org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAn
- Two's Complement
- 初试 Github
- TF-IDF
- js对象的声明方式
- 在Windows 64位操作系统上运行32位的vbscript