2013-04-07 24 views
0

我想在Windows上綁定一個TCP套接字,並期待從函數返回一個整數我得到一個編譯錯誤。我不是一名C++程序員,通常不能在Windows上工作,所以我無法跟蹤這個問題。我注意到的一件事是,如果我沒有包含winsock頭文件,我使用其他所有函數處理send,recv,accept和connect等所有引發編譯錯誤,但沒有爲綁定函數引發一個函數。這導致我相信我是一些如何拉動不同的綁定功能,然後我期待。Windows套接字API綁定函數編譯問題

包含的頭文件的整個應用程序

#include <fstream> 
#include <string> 
#include <ctime> 
#include <mutex> 
#include <stdio.h> 
#include <strsafe.h> 
#include <map> 
#include <iterator> 
#include <process.h> 
#include <queue> 
#include <iostream> 
#include <winsock.h> 

列表中包括圖書館是

#pragma comment(lib, "Ws2_32.lib") 
#pragma comment(lib, "User32.lib") 

,這是試圖使用綁定功能的類是

//implement an interface for udp and tcp socket classes to implement 
class Socket 
{ 
public: 
    virtual void sendm(const char *buf) = 0; 
    virtual int recvm(char *buf) = 0; 

    struct hostent *phe;  /* pointer to host information entry */ 
    struct servent *pse;  /* pointer to service information entry */ 
    struct protoent *ppe;  /* pointer to protocol information entry */ 
    struct sockaddr_in sin;  /* an Internet endpoint address  */ 
    int type, status;  /* socket descriptor and socket type */ 
    SOCKET s;     /* socket */ 
}; 

class TCPSocket : public Socket { 
public: 
    TCPSocket(const char *host, const char *service, bool master_socket){ 
     initialize_socket(host, service, master_socket); 
    } 
    ~TCPSocket(void); 


    SOCKET initialize_socket(const char *host, const char *service, bool master_socket) { 
     cout << "host: " << host << endl; 
     cout << "service: " << service << endl; 
     char* transport = "tcp"; 
     int qlen = 10; 
     int portbase = 0; 
     memset(&sin, 0, sizeof(sin)); 
     sin.sin_family = AF_INET; 
     if (pse = getservbyname(service, transport)) { 
      sin.sin_port = htons(ntohs((u_short)pse->s_port) + portbase); 
     } 
     else if ((sin.sin_port = htons((u_short)atoi(service))) == 0) 
     { 
      cout << "can't get " << service << " service" << endl; 
      exit(1); 
     } 

     /* Map protocol name to protocol number */ 
     if ((ppe = getprotobyname(transport)) == 0) { 
      cout << "Can't get \"" << transport << "\" protocol entry "<< endl; 
      exit(1); 
     } 

     /* Map host name to IP address, allowing for dotted decimal */ 
     if (master_socket) { 
      sin.sin_addr.s_addr = htonl(INADDR_ANY); 
     } 
     else { 
      if (phe = gethostbyname(host)) { 
       memcpy(&sin.sin_addr, phe->h_addr, phe->h_length); 
      } 
      else if ((sin.sin_addr.s_addr = inet_addr(host)) == INADDR_NONE) { 
       cout << "Can't get \"" << host << "\" IP address "<< endl; 
       exit(1); 
      } 
     } 


     type = SOCK_STREAM; 

     s = socket(AF_INET, type, ppe->p_proto); 

     if (s == INVALID_SOCKET) { 
      cout << "Socket Error: " << GetLastError() << endl; 
      exit(1); 
     } 

     if (master_socket) {  
      status = bind(s, (sockaddr *)&sin, sizeof(sin)); 
      /* if (status != 0) { */ 
      /* cout << "Bind Error: " << service << " port: " << GetLastError(); */ 
      /* } */ 
      status = listen(s, qlen); 
      if (status != 0) { 
       cout << "can't listen on " << service << " port: " << GetLastError(); 
       exit(1); 
      } 
     } else {  
      int status = connect(s, (struct sockaddr*)&sin, sizeof(sin)); 
      if (status != 0) { 
       cout << "could not connect" << endl; 
       exit(1); 
      } 
     } 
     return s;  
    } 

    SOCKET acceptSocket() { 
     return accept(s, (struct sockaddr*)&sin, (int*)sizeof(sin)); 
    } 

    void sendm(const char *buf) { 
     send(s, buf, strlen(buf), 0); 
    } 

    int recvm(char *buf) { 
     return recv(s, buf, BUFFER_SIZE, 0); 
    } 
}; 

關於msdn上bind的文檔說這個函數返回一個int。

編譯錯誤試圖編譯的時候我得到的是

error C2440: '=' : cannot convert from 'std::_Bind<_Forced,_Ret,_Fun,_V0_t,_V1_t,_V2_t,_V3_t,_V4_t,_V5_t,<unnamed-symbol>>' to 'int' 
with 
[ 
    _Forced=false, 
    _Ret=void, 
    _Fun=SOCKET &, 
    _V0_t=sockaddr *, 
    _V1_t=unsigned int, 
    _V2_t=std::_Nil, 
    _V3_t=std::_Nil, 
    _V4_t=std::_Nil, 
    _V5_t=std::_Nil, 
    <unnamed-symbol>=std::_Nil 
] 
No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called 

我與在VirtualBox中虛擬機的Windows 8上運行的工作。我正在使用Visual Studios 2012命令開發人員命令行來編譯我的代碼。任何建議,爲什麼綁定不能按預期工作將非常感激。

回答

2

這使我相信我是一些如何拉動不同的 綁定函數,然後我期待。

是的,你正在拉std::bind。如果你看裏面0​​它有這條線#include <functional>其中包括std::bind。 您可能有一個using namespace std;某處,它使std命名空間中的所有名稱都可見。

此外,你想要的綁定是在Winsock2.h,我沒有看到它的#include。請參閱Why is 'using namespace std;' considered a bad practice in C++?。我建議刪除任何使用指令(這可能是此問題的原因)並完全限定所有內容。

+1

一旦有部分是固定的,qualifiying'當bind'正確的':: bind' - 或任何命名空間的窗口API正在使用該功能 - 應該解決問題。 – didierc 2013-04-07 21:53:58

+0

真棒謝謝你解決它。我使用互斥鎖綁定函數,而不是使用正確的winsock頭。 – 2013-04-07 22:05:02

2

使用<mutex>,並有 「使用命名空間std」

使用::bind()代替bind()