17

I've been following Beej Networking guide and in the server section there is portion of code where it has called a function 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);

I'm on a windows machine and cant get that part working. What can I do to solve this?. My code is as follows.

/* 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;

}
MD XF
  • 7,860
  • 7
  • 40
  • 71
silent
  • 2,836
  • 10
  • 47
  • 73
  • 8
    When you code for Windows, you usually use another kind of thinking. I think you are better off looking at Winsock tutorials instead of this guide you are using. – Prof. Falken Nov 22 '10 at 09:39
  • Related questions: [What is the closest thing windows has to fork()?](http://stackoverflow.com/questions/985281/), [CreateThread vs fork()](http://stackoverflow.com/questions/619019/), [fork/chroot equivalent for Windows server application](http://stackoverflow.com/questions/1686578/), [Where does Microsoft Windows 7 POSIX implementation currently stands?](http://stackoverflow.com/questions/4746043/) – Piotr Dobrogost Mar 21 '11 at 20:06

3 Answers3

28

Contrary to both existing answers (from OJ and Vincent Robert) fork() does exist on high-end versions of Windows. It's part of Subsystem for UNIX-based Applications (SUA) earlier called Microsoft Windows Services for UNIX (SFU), earlier called Interix.

Citing http://en.wikipedia.org/wiki/Interix, SUA is available on

  • Windows Server 2003 R2 (all editions) - version 5.2
  • Windows Vista (Ultimate and Enterprise editions) - version 6.0
  • Windows Server 2008 (all editions) - version 6.0
  • Windows Server 2008 R2 and Microsoft Windows 7 - version 6.1

All you have to do to use fork() is to install free SUA SDK. Depending on your target system you need one of the following:

You can also take a look at Does Interix implement fork()?

Community
  • 1
  • 1
Piotr Dobrogost
  • 41,292
  • 40
  • 236
  • 366
  • 7
    So what you're saying is "Fork does exist so long as you make sure it does by either using the correct version of Windows and installing an SDK that enables it". IMHO, it may as well not exist. `CreateProcess` is a much easier and better option for Windows dev (imho of course). Cheers! – OJ. Mar 20 '11 at 23:44
  • 11
    No Windows is an easier and much better option. – Matt Joiner Mar 22 '11 at 05:37
  • 10
    Sadly it seems SUA is deprecated in Windows 8, and "will be completely removed from the next release": http://brianreiter.org/2011/09/15/sua-deprecated-in-windows-8/ – RichieHindle Nov 29 '12 at 14:11
  • 3
    @RichieHindle But now we are about to get a replacement in WSL apparently: https://en.wikipedia.org/wiki/Windows_Subsystem_for_Linux – Søren Boisen Apr 15 '16 at 14:14
  • @SørenBoisen: Yes! I've yet to look at it, but it does look very promising. We're currently using Cygwin, which isn't the most stable of things. A "real" Linux commandline subsystem for Windows ought to be a much better alternative. – RichieHindle Apr 16 '16 at 07:12
  • 1
    @RichieHindle Why not just use GNU/Linux then? It'll give you the most "real" Linux command line then. With WSL your abilities are limited. – tripulse Dec 24 '21 at 08:04
10

fork() obviously doesn't exist on Windows. Instead you'll need to create a new thread, or a whole new process.

OJ.
  • 28,944
  • 5
  • 56
  • 71
6

fork does not exist on Windows. You have to use a Window specific API called CreateProcess.

Contrary to fork, CreateProcess needs the path to the EXE. You can retrieve the path of the current EXE by calling GetModuleFileName with a NULL parameter.

Vincent Robert
  • 35,564
  • 14
  • 82
  • 119