【问题标题】:Substitute for forking in windows在 windows 中替代 fork
【发布时间】:2023-03-24 04:37:01
【问题描述】:

我一直在关注Beej Networking guide,在服务器部分有一部分代码调用了函数 fork()。

if (!fork()) { // this is the child process
            close(sockfd); // child doesn't need the listener
            if (send(new_fd, "Hello, world!", 13, 0) == -1)
                perror("send");
            close(new_fd);
            exit(0);

我在 Windows 机器上,无法使该部分正常工作。我能做些什么来解决这个问题? 我的代码如下。

/* Server */
#define _WIN32_WINNT 0x501
#include <iostream>
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#include  <sys/types.h>


using namespace std;

const int winsockVersion = 2;
#define BACKLOG 10
#define PORT "3000"


int main(void){

    WSADATA wsadata;
    if (WSAStartup(MAKEWORD(winsockVersion,0),&wsadata) == 0){
        cout<<"-WSAStartup initialized..." << endl;

        int status;
        int sockfd, new_fd;
        const char yes = '1';
        struct addrinfo hints, *res,*loop_find;
        struct sockaddr_storage their_addr;
        socklen_t addr_size;



        memset(&hints,0,sizeof hints);
        hints.ai_family = AF_INET;
        hints.ai_socktype = SOCK_STREAM;
        hints.ai_flags = AI_PASSIVE;

        if ( (status = getaddrinfo(NULL,PORT,&hints,&res)) == 0 ){
            cout<<"-Call to get addrinfo successful!." << endl;
        }

        for (loop_find = res; loop_find!=NULL; loop_find = loop_find->ai_next){
            if ( (sockfd = socket(loop_find->ai_family,loop_find->ai_socktype,loop_find->ai_protocol) ) == -1 ){
                cout<<"-Could not create socket." << endl;
                continue;
            }else{
                cout<<"-Socket Created." << endl;
            }

            //clearing in use ports.
            if (setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int)) == -1) {
                cout<<"-Couldnt clear blocked port." << endl;
                perror("setsockopt");
                exit(1);
            }

            if( bind(sockfd,loop_find->ai_addr,loop_find->ai_addrlen) == -1 ){
                closesocket(sockfd);
                perror("server: bind");
                continue;
            }

            break;
        }

        if (listen(sockfd,BACKLOG) != -1){
            cout<<"-Listening for incoming connections.";
        }

        //accept loop.
        while(true){

            socklen_t addr_size = sizeof their_addr;
            new_fd = accept(sockfd,(sockaddr*)&their_addr,&addr_size);

            if ( new_fd == -1 ){
                perror("accept");
                continue;
            }

            struct sockaddr new_addr;
            int len = sizeof new_addr;
            getpeername(new_fd,&new_addr,&len);
            cout<<"-Connected to " << new_addr.sa_data << endl;

            if(!fork()){ //this is a child process
                closesocket(sockfd);
                if (send(new_fd,"hello world!!",13,0) == -1){
                    perror("send");
                    closesocket(new_fd);
                    exit(0);
                }
            }
            closesocket(new_fd);

        }
    }


    //clear stuff
    if( WSACleanup() != 0){
        cout<<"-WSACleanup unsuccessful" << endl;
    }else{
        cout<<"-WSACleanup successful" << endl;
    }


    return 0;

}

【问题讨论】:

标签: c++ winapi gcc winsock fork


【解决方案1】:

fork 在 Windows 上不存在。您必须使用名为 CreateProcess 的 Window 特定 API。

fork 相反,CreateProcess 需要 EXE 的路径。您可以通过调用GetModuleFileName,使用NULL参数来检索当前EXE的路径。

【讨论】:

  • fork() 在 Windows 上确实存在 :) 看我的回答。
【解决方案2】:

fork() 显然在 Windows 上不存在。相反,您需要 create a new threadwhole new process

【讨论】:

  • 但实际上你根本不会像在 Windows 上那样设计网络服务器。
  • fork() 在 Windows 上不那么明显 确实存在 :) 看我的回答。
  • 听上去像个狂热分子。如果你问我,毫无意义的评论。
【解决方案3】:

与现有答案(来自 OJ 和文森特罗伯特)相反,fork() 确实存在于高端版本的 Windows 上。它是 基于 UNIX 的应用程序的子系统 (SUA) 的一部分,之前称为 Microsoft Windows Services for UNIX (SFU),之前称为 Interix。 p>

引用http://en.wikipedia.org/wiki/Interix,SUA 可在

  • Windows Server 2003 R2(所有版本)- 5.2 版
  • Windows Vista(终极版和 企业版)- 6.0 版
  • Windows Server 2008(所有版本)- 6.0版
  • Windows Server 2008 R2 和微软 Windows 7 - 6.1 版

使用 fork() 只需安装免费的SUA SDK。根据您的目标系统,您需要以下之一:

你也可以看看Does Interix implement fork()?

【讨论】:

  • 所以您的意思是“Fork 确实存在,只要您通过使用正确版本的 Windows 并安装启用它的 SDK 来确保它确实存在”。恕我直言,它也可能不存在。 CreateProcess 对于 Windows 开发人员来说是一个更容易和更好的选择(当然是恕我直言)。干杯!
  • 无 Windows 是一个更简单、更好的选择。
  • 遗憾的是,在 Windows 8 中似乎不推荐使用 SUA,并且“将从下一个版本中完全删除”:brianreiter.org/2011/09/15/sua-deprecated-in-windows-8
  • @RichieHindle 但是现在我们显然要在 WSL 中找到一个替代品:en.wikipedia.org/wiki/Windows_Subsystem_for_Linux
  • @SørenBoisen:是的!我还没有看它,但它看起来确实很有希望。我们目前正在使用 Cygwin,它不是最稳定的。用于 Windows 的“真正的”Linux 命令行子系统应该是更好的选择。
猜你喜欢
  • 2019-01-05
  • 1970-01-01
  • 2013-02-17
  • 1970-01-01
  • 2016-07-19
  • 2012-08-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多