Windows平台基于多进程的echo服务器简单实现
来源:互联网 发布:批发建筑材料的软件 编辑:程序博客网 时间:2024/06/04 19:46
这里的Echo服务器就是说客户端发什么,服务器端立刻返回什么。一种常见的实现是基于多线程的,在linux上还很容易就用fork实现一个多进程的服务器。
下面演示一下在Windows平台如何用多进程来实现一个echo服务器。
/* * @file : TestEchoServerMultiProcess.cpp * @author: Shilyx * @date : 2014-04-23 08:43:27.206 * @note : Generated by SlxTemplates, 多进程echo服务器演示 */#include <WinSock2.h>#include <Windows.h>#include <Shlwapi.h>#pragma warning(disable: 4786)#include <iostream>#pragma comment(lib, "Ws2_32.lib")#pragma comment(lib, "Shlwapi.lib")using namespace std;// 初始化WinSock,未检查返回值void InitWinSock(){ WSADATA wd; WSAStartup(MAKEWORD(2, 2), &wd);}void Serve(USHORT port){ InitWinSock(); SOCKET sock_base = INVALID_SOCKET; do { sock_base = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (sock_base == INVALID_SOCKET) { cerr<<"socket error "<<WSAGetLastError()<<endl; break; } sockaddr_in sin; sin.sin_family = AF_INET; sin.sin_addr.s_addr = INADDR_ANY; sin.sin_port = htons(port); if (SOCKET_ERROR == bind(sock_base, (sockaddr *)&sin, sizeof(sin))) { cerr<<"bind error "<<WSAGetLastError()<<endl; break; } if (SOCKET_ERROR == listen(sock_base, 100)) { cerr<<"listen error "<<WSAGetLastError()<<endl; break; } HANDLE hProcess = NULL; DuplicateHandle(GetCurrentProcess(), GetCurrentProcess(), GetCurrentProcess(), &hProcess, 0, TRUE, DUPLICATE_SAME_ACCESS); if (NULL == hProcess) { cerr<<"DuplicateHandle error "<<GetLastError()<<endl; break; } TCHAR szSelfPath[MAX_PATH]; GetModuleFileName(GetModuleHandle(NULL), szSelfPath, RTL_NUMBER_OF(szSelfPath)); PathQuoteSpaces(szSelfPath); while (true) { int len = sizeof(sin); SOCKET sock = accept(sock_base, (sockaddr *)&sin, &len); if (sock == INVALID_SOCKET) { cerr<<"accept error "<<WSAGetLastError()<<endl; break; } else { TCHAR szCommand[MAX_PATH * 2]; STARTUPINFO si = {sizeof(si)}; PROCESS_INFORMATION pi; si.dwFlags = STARTF_USESHOWWINDOW; si.wShowWindow = SW_SHOW; wnsprintf(szCommand, RTL_NUMBER_OF(szCommand), TEXT("%s %u %u"), szSelfPath, sock, hProcess); if (CreateProcess(NULL, szCommand, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi)) { CloseHandle(pi.hProcess); CloseHandle(pi.hThread); } else { cerr<<"CreateProcess error "<<GetLastError()<<endl; } closesocket(sock); } } } while (false); if (sock_base != INVALID_SOCKET) { closesocket(sock_base); }}DWORD CALLBACK WorkProc(LPVOID lpParam){ SOCKET sock = (SOCKET)lpParam; while (TRUE) { char szBuffer[4096]; int len = recv(sock, szBuffer, sizeof(szBuffer), 0); if (len <= 0) { break; } if (send(sock, szBuffer, len, 0) <= 0) { break; } } closesocket(sock); return 0;}void Work(SOCKET sock, HANDLE hParentProcess){ InitWinSock(); HANDLE hObjects[] = {hParentProcess, CreateThread(NULL, 0, WorkProc, (LPVOID)sock, 0, NULL)}; WaitForMultipleObjects(RTL_NUMBER_OF(hObjects), hObjects, FALSE, INFINITE); CloseHandle(hObjects[0]); CloseHandle(hObjects[1]);}int main(int argc, char *argv[]){ // 加端口参数启动为父进程 // 加套接字句柄参数和进程句柄参数为子进程 // 不加参数显示用法 if (argc == 2) { int port = StrToIntA(argv[1]); if (port < 0 || port > 65535) { cerr<<"端口错误:"<<port<<endl; return 0; } // 在端口port处启动echo服务器 Serve((USHORT)port); } else if (argc == 3) { SOCKET sock = StrToIntA(argv[1]); HANDLE hParentProcess = (HANDLE)StrToIntA(argv[2]); // 针对具体tcp连接套接字和父进程句柄开始echo工作 Work(sock, hParentProcess); } else { cout<<"加端口参数启动为父进程"<<endl <<"加套接字句柄参数和进程句柄参数为子进程"<<endl <<"不加参数显示用法"<<endl; } return 0;}
- Windows平台基于多进程的echo服务器简单实现
- epoll实现简单echo服务器
- C++实现基于IO复用模型的echo服务器
- 简单的echo服务器与客户端的实现
- 简单的echo服务器程序
- [UNIX网络编程] sun rpc实现的简单echo服务器
- socket实现简单的echo应答服务器和客户端
- Linux下实现简单Echo中继服务器
- 基于boost.asio的ECHO服务器
- 基于boost.asio的echo服务器2
- 基于boost.asio的echo服务器3
- 6.基于poll的TCP echo服务器
- 【slighttpd】基于lighttpd架构的Server项目实战(4)—简单的echo服务器
- windows下的TCP并发ECHO服务器
- c++实现基于单进程单客户编程模型的echo程序
- python实现-恒定数量进程池的echo server模型 基于multiprocessing
- Boost::Asio一个简单的Echo服务器
- boost::asio一个简单的echo服务器
- Qt学习之对话框与主窗口的创建
- cocos2d-x手机游戏开发笔记(二)--坐标系
- 剑指Offer算法实现之十九:二叉树的镜像
- Threads in Spring
- 基于Tomcat7、Java、WebSocket的服务器推送聊天室
- Windows平台基于多进程的echo服务器简单实现
- 每日一题(62) - 和为s的连续正整数序列
- Elastisearch相关
- KeyCode键码值表
- .NET框架设计—常被忽视的框架设计技巧
- 开源中国iOS客户端学习——(一)Prefix.pch文件
- Fedora9下解决无ifconfig指令
- since的用法.
- linux内核学习第三天——内核模块的加载