2010-11-22 10 views
10

Tôi đã theo dõi Beej Networking guide và trong phần máy chủ có một phần mã mà nó đã gọi là hàm fork().Thay thế forking trong cửa sổ

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); 

Tôi đang ở trên máy tính và không thể làm việc đó. Tôi có thể làm gì để giải quyết vấn đề này ?. Mã của tôi như sau.

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

} 
+6

Khi bạn mã cho Windows, bạn thường sử dụng một loại suy nghĩ khác. Tôi nghĩ bạn nên nhìn vào hướng dẫn Winsock thay vì hướng dẫn này bạn đang sử dụng. –

+0

câu hỏi liên quan: [cửa sổ điều gần nhất có gì để ngã ba()?] (Http://stackoverflow.com/questions/985281/), [CreateThread vs fork()] (http://stackoverflow.com/questions/619019 /), [fork/chroot tương đương với ứng dụng máy chủ Windows] (http://stackoverflow.com/questions/1686578/), [Microsoft Windows 7 POSIX hiện đang ở đâu?] (Http://stackoverflow.com/questions/4746043 /) –

Trả lời

6

fork() rõ ràng không tồn tại trên Windows. Thay vào đó, bạn sẽ cần phải create a new thread hoặc whole new process.

+8

Nhưng trong thực tế bạn chỉ đơn giản là không thiết kế các máy chủ mạng như thế trên Windows. –

+0

+1 :) Tôi chắc chắn sẽ không tha thứ cho nó. –

+3

fork() không hiển nhiên ** tồn tại ** trên Windows :) Xem câu trả lời của tôi. –

5

fork không tồn tại trên Windows. Bạn phải sử dụng API cụ thể của Cửa sổ được gọi là CreateProcess.

Tương phản với fork, CreateProcess cần đường dẫn đến EXE. Bạn có thể lấy đường dẫn của EXE hiện tại bằng cách gọi GetModuleFileName với tham số NULL.

+1

fork() ** không tồn tại ** trên Windows :) Xem câu trả lời của tôi. –

18

Trái với cả câu trả lời hiện có (từ OJ và Vincent Robert) fork() không tồn tại trên các phiên bản cao cấp của Windows. Nó là một phần của Hệ thống con cho các ứng dụng dựa trên UNIX (SUA) trước đó được gọi là Dịch vụ Microsoft Windows cho UNIX (SFU), trước đó được gọi là Interix.

Trích dẫn http://en.wikipedia.org/wiki/Interix, SUA có sẵn trên

  • Windows Server 2003 R2 (mọi phiên bản) - Phiên bản 5.2
  • Windows Vista (Ultimate và phiên bản Enterprise) - phiên bản 6.0
  • Windows Server 2008 (tất cả các ấn bản) - phiên bản 6.0
  • Windows Server 2008 R2 và Microsoft Windows 7 - phiên bản 6.1

Tất cả những gì bạn phải làm để sử dụng fork() là cài đặt miễn phí SUA SDK. Tùy thuộc vào hệ thống mục tiêu của bạn, bạn cần một trong các cách sau:

Bạn cũng có thể có một cái nhìn tại Does Interix implement fork()?

+3

Vì vậy, những gì bạn đang nói là "Fork tồn tại miễn là bạn chắc chắn rằng nó bằng cách sử dụng phiên bản chính xác của Windows và cài đặt một SDK cho phép nó". IMHO, nó cũng có thể không tồn tại. 'CreateProcess' là một lựa chọn dễ dàng hơn và tốt hơn cho Windows dev (tất nhiên là imho). Chúc mừng! –

+10

Không Windows là một lựa chọn dễ dàng hơn và tốt hơn nhiều. –

+7

Đáng buồn thay, dường như SUA không được chấp nhận trong Windows 8 và "sẽ bị xóa hoàn toàn khỏi bản phát hành tiếp theo": http://brianreiter.org/2011/09/15/sua-deprecated-in-windows-8/ – RichieHindle