Windows版本fock(TODO)

// ConsoleApplication.cpp : This file contains the 'main' function. Program
// execution begins and ends there.
//
//TODO from dcmtk

#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>

#include <winsock2.h> /* for SO_EXCLUSIVEADDRUSE */
#include <ws2tcpip.h> /* for socklen_t */
#include <sstream>
#include <string>

#include <iostream>
#ifdef HAVE_IOS
#include <ios>
#endif
#include <fstream>
#include <iomanip>
// For standard STREAMS library: preference for standard stringstream
#if defined(HAVE_SSTREAM)
#include <sstream>
#define USE_STRINGSTREAM
#elif defined(HAVE_STRSTREAM)
#include <strstream>
#else
#endif

//begin
// Definition of type OFBool

#ifdef _WIN32
static char **command_argv = NULL;
static int command_argc = 0;
#endif

typedef bool OFBool;
#define OFTrue true
#define OFFalse false

#define OFString std::string

// define STD_NAMESPACE to std:: if the standard namespace exists
#ifndef STD_NAMESPACE
#ifdef HAVE_STD_NAMESPACE
#define STD_NAMESPACE std::
#else
#define STD_NAMESPACE
#endif
#endif

typedef STD_NAMESPACE stringstream OFStringStream;
typedef STD_NAMESPACE ostringstream OFOStringStream;
typedef STD_NAMESPACE istringstream OFIStringStream;

#define OFStringStream_ends ""

#define OFconst_cast(x, y) (const_cast<x>(y))
#define OFreinterpret_cast(x, y) (reinterpret_cast<x>(y))
#define OFstatic_cast(x, y) (static_cast<x>(y))

#ifdef HAVE_STL_STRING
#define OFSTRINGSTREAM_GETOFSTRING(oss, strng) OFString strng((oss).str());
#else
#define OFSTRINGSTREAM_GETOFSTRING(oss, strng) \
  STD_NAMESPACE string strng##__((oss).str()); \
  OFString strng(strng##__.c_str(), strng##__.length());
#endif

#pragma comment(lib, "Ws2_32.lib")
//#define makeDcmnetCondition(A, B, C) makeOFCondition(OFM_dcmnet, (A), (B),
//(C))

/** this enumeration describes the return status of an operation.
 */
enum OFStatus {
  /// no error, operation has completed successfully
  OF_ok,

  /// operation has not completed successfully
  OF_error,

  /// application failure
  OF_failure
};


static bool ReceiveTransportConnectionTCP(int command_argc,
                                          char **command_argv) {
  //#elif defined(_WIN32)

    //initializeNetworkTCP
#ifdef _WIN32
  SOCKET sock;
#else
  int sock;
#endif

  WSADATA wsa;


  printf("\nInitialising Winsock...");
  if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0) {
    printf("Failed. Error Code : %d", WSAGetLastError());
    return 1;
  }

  printf("Initialised.\n");

  if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {
    printf("Could not create socket : %d", WSAGetLastError());
  }

  printf("Socket created.\n");
  //SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
  //{
    struct linger sockarg;
    int reuse = 1;

    (void)memset(&sockarg, 0, sizeof(sockarg));

 
    {

//#ifdef HAVE_DECLARATION_SOCKLEN_T
     socklen_t length;
//#elif !defined(HAVE_PROTOTYPE_ACCEPT) || defined(HAVE_INTP_ACCEPT)
//      int length;
//#else
//          size_t length;
//#endif


      struct sockaddr_in server;

      /* Create socket for Internet type communication */
      //(*key)->networkSpecific.TCP.port = *(int *)parameter;
      //(*key)->networkSpecific.TCP.listenSocket =
    //  sock = socket(AF_INET, SOCK_STREAM, 0);
      //(*key)               ->networkSpecific.TCP.listenSocket;

      if (sock == INVALID_SOCKET)
      {
        OFString msg = "TCP Initialization Error: ";
        //msg += OFStandard::getLastNetworkErrorCode().message();
        //return makeDcmnetCondition(DULC_TCPINITERROR, OF_error, msg.c_str());
        return false;
      }
      reuse = 1;
#ifdef _WIN32
      if (setsockopt(sock, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (char *)&reuse,
                     sizeof(reuse)) < 0)
#else
      if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse,
                     sizeof(reuse)) < 0)
#endif
      {
        OFString msg = "TCP Initialization Error: ";
        //msg += OFStandard::getLastNetworkErrorCode().message();
        //return makeDcmnetCondition(DULC_TCPINITERROR, OF_error, msg.c_str());
        return false;
      }

      /* Name socket using wildcards */
      server.sin_family = AF_INET;
      server.sin_addr.s_addr = INADDR_ANY;
      server.sin_port = 103;
      //(unsigned short)htons((*key)->networkSpecific.TCP.port);
      if (bind(sock, (struct sockaddr *)&server, sizeof(server))) {
        OFString msg = "TCP Initialization Error: ";
        //msg += OFStandard::getLastNetworkErrorCode().message();
        //return makeDcmnetCondition(DULC_TCPINITERROR, OF_error, msg.c_str());
        return false;
      }
      /* Find out assigned port number and print it out */
      length = sizeof(server);
      if (getsockname(sock, (struct sockaddr *)&server, &length)) {
        OFString msg = "TCP Initialization Error: ";
        //msg += OFStandard::getLastNetworkErrorCode().message();
        //return makeDcmnetCondition(DULC_TCPINITERROR, OF_error, msg.c_str());
        return false;
      }
      sockarg.l_onoff = 0;
      if (setsockopt(sock, SOL_SOCKET, SO_LINGER, (char *)&sockarg,
                     sizeof(sockarg)) < 0) {
        OFString msg = "TCP Initialization Error: ";
        //msg += OFStandard::getLastNetworkErrorCode().message();
        //return makeDcmnetCondition(DULC_TCPINITERROR, OF_error, msg.c_str());
        return false;
      }

      /* Listen on the socket */
#define PRV_LISTENBACKLOG 50
      if (listen(sock, PRV_LISTENBACKLOG) < 0) {
        OFString msg = "TCP Initialization Error: ";
        //msg += OFStandard::getLastNetworkErrorCode().message();
        //return makeDcmnetCondition(DULC_TCPINITERROR, OF_error, msg.c_str());
        return false;
      }
    }

    //(*key)->networkSpecific.TCP.tLayer = new DcmTransportLayer();
    //(*key)->networkSpecific.TCP.tLayerOwned = 1;
    //if (NULL == (*key)->networkSpecific.TCP.tLayer) {
    //  return makeDcmnetCondition(DULC_TCPINITERROR, OF_error,
    //                             "Cannot initialize DcmTransportLayer");
    //}
  //}


  //= dcmExternalSocketHandle.get();

 bool shouldFork = true;
  if (shouldFork /*&& (command_argc > 0) && command_argv*/) {
    // win32 code to create new child process
    HANDLE childSocketHandle;
    HANDLE hChildStdInRead;
    HANDLE hChildStdInWrite;
    HANDLE hChildStdInWriteDup;

    SECURITY_ATTRIBUTES sa;
    sa.nLength = sizeof(SECURITY_ATTRIBUTES);
    sa.bInheritHandle = TRUE;
    sa.lpSecurityDescriptor = NULL;

    // prepare the command line
    OFString cmdLine = command_argv[0];
    //"D:\\code\\ConsoleApp\\ConsoleApplication\\Debug\\ConsoleApplication.exe";

    cmdLine += " --forked-child";
    for (int i = 1; i < command_argc; ++i) {
      /* copy each argv value and surround it with double quotes
       * to keep option values containing a space glued together
       */
      cmdLine += " \"";
      cmdLine += command_argv[i];
      /* if last character in argument value is a backslash, escape it
       * since otherwise it would escape the quote appended in the following
       * step, i.e. make sure that something like '\my\dir\' does not become
       * '"\my\dir\"' but instead ends up as '"\my\dir\\"' (single quotes for
       *  demonstration purposes). Make sure nobody passes a zero length string.
       */
      size_t len = strlen(command_argv[i]);
      if ((len > 0) && (command_argv[i][len - 1] == '\\')) {
        cmdLine += "\\";
      }
      cmdLine += "\"";
    }
    std::cout << cmdLine << "\n";

    // create anonymous pipe
    if (!CreatePipe(&hChildStdInRead, &hChildStdInWrite, &sa, 0)) {
      OFOStringStream stream;
      stream
          << "Multi-Process Error: Creating anonymous pipe failed with error "
             "code "
          << GetLastError() << OFStringStream_ends;
      OFSTRINGSTREAM_GETOFSTRING(stream, msg);
      // return makeDcmnetCondition(DULC_CANNOTFORK, OF_error, msg.c_str());
      return false;
    }

    // create duplicate of write end handle of pipe
    if (!DuplicateHandle(GetCurrentProcess(), hChildStdInWrite,
                         GetCurrentProcess(), &hChildStdInWriteDup, 0, FALSE,
                         DUPLICATE_SAME_ACCESS)) {
      // return makeDcmnetCondition(DULC_CANNOTFORK, OF_error, "Multi-Process
      // Error: Duplicating handle failed");
      return false;
    }

    // destroy original write end handle of pipe
    CloseHandle(hChildStdInWrite);

    // we need a STARTUPINFO and a PROCESS_INFORMATION structure for
    // CreateProcess.
    STARTUPINFOA si;
    PROCESS_INFORMATION pi;
    memset(&pi, 0, sizeof(pi));
    memset(&si, 0, sizeof(si));

    // prepare startup info for child process:
    // the child uses the same stdout and stderr as the parent, but
    // stdin is the read end of our anonymous pipe.
    si.cb = sizeof(si);
    si.dwFlags |= STARTF_USESTDHANDLES;
    si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
    si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
    si.hStdInput = hChildStdInRead;

    // create child process.
    if (!CreateProcessA(NULL, OFconst_cast(char *, cmdLine.c_str()), NULL, NULL,
                        TRUE, 0, NULL, NULL, &si, &pi)) {
      OFOStringStream stream;
      stream << "Multi-Process Error: Creating process failed with error code "
             << GetLastError() << OFStringStream_ends;
      OFSTRINGSTREAM_GETOFSTRING(stream, msg)
      // return makeDcmnetCondition(DULC_CANNOTFORK, OF_error, msg.c_str());
      return false;
    } else {
      // call OpenProcess to retrieve the REAL process handle.  using
      // GetCurrentProcess() only returns a pseudo handle which may not
      // allow DuplicateHandle to create the child process socket with
      // sufficient permissions on certain versions of Windows.
      HANDLE hParentProcessHandle =
          OpenProcess(PROCESS_DUP_HANDLE, FALSE, GetCurrentProcessId());
      if (hParentProcessHandle == NULL) {
        // unable to get process handle...
        // ...this should really never happen as we are opening the current
        // process.
        CloseHandle(pi.hProcess);
        CloseHandle(pi.hThread);
        CloseHandle((HANDLE)sock);

        OFOStringStream stream;
        stream << "Multi-Process Error: Opening process to get real process "
                  "handle failed with error code "
               << GetLastError() << OFStringStream_ends;
        OFSTRINGSTREAM_GETOFSTRING(stream, msg)
        // return makeDcmnetCondition(DULC_CANNOTFORK, OF_error, msg.c_str());
        return false;
      }

      // PROCESS_INFORMATION pi now contains various handles for the new
      // process. Now that we have a handle to the new process, we can duplicate
      // the socket handle into the new child process.
      if (DuplicateHandle(hParentProcessHandle, (HANDLE)sock, pi.hProcess,
                          &childSocketHandle, 0, TRUE, DUPLICATE_SAME_ACCESS)) {
        // close handles in PROCESS_INFORMATION structure
        // and our local copy of the socket handle.
        CloseHandle(hParentProcessHandle);
        CloseHandle(pi.hProcess);
        CloseHandle(pi.hThread);
        closesocket(sock);

        // send number of socket handle in child process over anonymous pipe
        DWORD bytesWritten;
        char buf[30];
        // we pass the socket handle as a 64-bit unsigned integer, which should
        // work for 32 and 64 bit Windows
        sprintf(buf, "%llu",
                OFreinterpret_cast(unsigned __int64, childSocketHandle));
        if (!WriteFile(hChildStdInWriteDup, buf,
                       OFstatic_cast(DWORD, strlen(buf) + 1), &bytesWritten,
                       NULL)) {
          CloseHandle(hChildStdInWriteDup);
          // return makeDcmnetCondition( DULC_CANNOTFORK,
          // OF_error,"Multi-Process Error: Writing to anonymous pipe failed");
          return false;
        }

        // return OF_ok status code DULC_FORKEDCHILD with descriptive text
        OFOStringStream stream;
        stream << "New child process started with pid "
               << OFstatic_cast(int, pi.dwProcessId) << ", socketHandle "
               << OFstatic_cast(int,
                                OFreinterpret_cast(size_t, childSocketHandle))
               << OFStringStream_ends;
        OFSTRINGSTREAM_GETOFSTRING(stream, msg);
        // return makeDcmnetCondition(DULC_FORKEDCHILD, OF_ok, msg.c_str());
           
        std::cout << "New child process started with pid=" << pi.dwProcessId
                  << "\n";
        return true;
} else {
        // unable to duplicate handle. Close handles nevertheless
        // to avoid resource leak.
        CloseHandle(hParentProcessHandle);
        CloseHandle(pi.hProcess);
        CloseHandle(pi.hThread);
        // return makeDcmnetCondition(DULC_CANNOTFORK, OF_error, "Multi-Process
        // Error: Duplicating socket handle failed");
        return false;
      }
    }
  }

  return true;
}
//#endif
int main(int command_argc, char **command_argv) {
  std::cout << "Hello World!\n";
  bool need_fork = true;
  for (int i = 1; i < command_argc; ++i) {
    if (std::string(command_argv[i]) == "--forked-child") {
      need_fork = false;
    }
  }

  if (need_fork) {
    bool bret = ReceiveTransportConnectionTCP(command_argc, command_argv);
    bret;
    std::cout << "forked-child input a number\n";
    int i = 0;
    std::cin >> i;
    std::cout << "end\n";

  }

   std::cout << "input a number\n";
    int i = 0;
   std::cin >> i;
  std::cout << "end\n";
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值