⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pnpserver.cxx

📁 PTypes (C++ Portable Types Library) is a simple alternative to the STL that includes multithreading
💻 CXX
字号:
/* * *  C++ Portable Types Library (PTypes) *  Version 1.7.5   Released 9-Mar-2003 * *  Copyright (c) 2001, 2002, 2003 Hovik Melikyan * *  http://www.melikyan.com/ptypes/ *  http://ptypes.sourceforge.net/ * */#ifdef WIN32#  include <windows.h>#else#  include <sys/time.h>#  include <sys/types.h>#  include <sys/socket.h>#  include <sys/un.h>#  include <unistd.h>#endif#include "pstreams.h"#include "pasync.h"PTYPES_BEGINnpserver::npserver(const string& ipipename)    : pipename(), handle(invhandle), active(false){    pipename = namedpipe::realpipename(ipipename);}npserver::~npserver(){    close();}void npserver::error(int code, const char* defmsg){    string msg = unixerrmsg(code);    if (isempty(msg))        msg = defmsg;    msg += " [" + pipename + ']';    throw new estream(nil, code, msg);}#ifdef WIN32void npserver::openinst(){    // called once at startup and then again, after     // each client connection. strange logic, to say the least...    SECURITY_ATTRIBUTES sa;    sa.nLength = sizeof(SECURITY_ATTRIBUTES);    sa.lpSecurityDescriptor = NULL;    sa.bInheritHandle = TRUE;    handle = (int)CreateNamedPipe(pipename,         PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,        PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,        PIPE_UNLIMITED_INSTANCES,         DEF_PIPE_SYSTEM_BUF_SIZE, DEF_PIPE_SYSTEM_BUF_SIZE,        DEF_PIPE_TIMEOUT, &sa);        if (handle == invhandle)        error(unixerrno(), "Couldn't create");}void npserver::closeinst(){    CloseHandle(HANDLE(pexchange(&handle, invhandle)));}#endifvoid npserver::open(){    close();#ifdef WIN32    openinst();#else    sockaddr_un sa;    if (!namedpipe::setupsockaddr(pipename, &sa))        error(ERANGE, "Socket name too long");    if ((handle = ::socket(sa.sun_family, SOCK_STREAM, 0)) < 0)        error(unixerrno(), "Couldn't create local socket");    unlink(pipename);    if (::bind(handle, (sockaddr*)&sa, sizeof(sa)) != 0)        error(unixerrno(), "Couldn't bind local socket");        if (::listen(handle, SOMAXCONN) != 0)        error(unixerrno(), "Couldn't listen on local socket");#endif    active = true;}void npserver::close(){    if (active)    {        active = false;#ifdef WIN32        closeinst();#else        ::close(pexchange(&handle, invhandle));        unlink(pipename);#endif    }}bool npserver::serve(namedpipe& client, int timeout){    if (!active)        open();    client.cancel();#ifdef WIN32    client.ovr.Offset = 0;    client.ovr.OffsetHigh = 0;    bool result = ConnectNamedPipe(HANDLE(handle), &client.ovr) ?        true : (GetLastError() == ERROR_PIPE_CONNECTED);    if (!result && GetLastError() == ERROR_IO_PENDING)    {        if (WaitForSingleObject(client.ovr.hEvent, timeout) == WAIT_TIMEOUT)            return false;        unsigned long ret;        if (!GetOverlappedResult(HANDLE(handle), &client.ovr, &ret, false))            error(unixerrno(), "Couldn't read");        result = true;    }    if (result)    {        client.svhandle = handle;        client.pipename = pipename;        openinst();        client.open();        return true;    }    else        error(unixerrno(), "Couldn't connect to client");    return false;#else    fd_set set;    FD_ZERO(&set);    FD_SET((uint)handle, &set);    timeval t;    t.tv_sec = timeout / 1000;    t.tv_usec = (timeout % 1000) * 1000;    if (::select(FD_SETSIZE, &set, nil, nil, (timeout < 0) ? nil : &t) > 0)    {        client.svhandle = handle;        client.pipename = pipename;        client.open();        return true;    }    return false;#endif}PTYPES_END

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -