简体   繁体   English

Windows套接字API绑定函数编译问题

[英]Windows socket api bind function compile issues

I am trying to bind a tcp socket on windows and when expecting an integer back from the function I get a compile error. 我试图在Windows上绑定一个TCP套接字,并且当期望该函数返回整数时,出现编译错误。 I am not a c++ programmer and usually do not work on Windows so I am having trouble tracking this issue down. 我不是c ++程序员,通常不能在Windows上工作,因此无法跟踪此问题。 One thing I did notice was that if I did not include the winsock header file all of the other functions I use dealing with sockets such as send, recv, accept and connect all raise compile errors but one was not raised for the bind function. 我注意到的一件事是,如果我不包括winsock头文件,那么我使用的所有其他处理套接字的函数(例如send,recv,accept和connect)都会引发编译错误,但没有为bind函数引发一个错误。 This leads me to believe that I am some how pulling in a different bind function then I am expecting. 这使我相信,我在某种程度上引入了与期望不同的绑定函数。

The list of included header files for the entire application 整个应用程序包含的头文件列表

#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>

The included library's are 包含的库是

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

And the class that is trying to use the bind function is 尝试使用bind函数的类是

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

The documentation on bind on msdn says this function returns an int. msdn上的bind文档说此函数返回一个int。

The compile error I get when attempting to compile is 我在尝试编译时遇到的编译错误是

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

I am working with Windows 8 running on a VM in VirtualBox. 我正在在VirtualBox中的VM上运行Windows 8。 I am using Visual Studios 2012 command developer command line to compile my code. 我正在使用Visual Studios 2012命令开发人员命令行来编译我的代码。 Any suggestions as to why bind is not working as expected would be very much appreciated. 关于为什么绑定不能按预期工作的任何建议将不胜感激。

This leads me to believe that I am some how pulling in a different bind function then I am expecting. 这使我相信,我在某种程度上引入了与期望不同的绑定函数。

Yes, you are pulling in std::bind . 是的,您正在拉入std :: bind If you look inside <mutex> it has this line #include <functional> which includes std::bind . 如果在<mutex>内部<mutex> ,则此行#include <functional>包括std::bind You probably have a using namespace std; 您可能有一个using namespace std; somewhere which makes all the names from the std namespace visible. 使std名称空间中所有名称可见的位置。

Also, the bind you want is in Winsock2.h , and I didn't see an #include for it. 另外,您想要的绑定位于Winsock2.h ,但我没有看到#include

Please read Why is 'using namespace std;' 请阅读为什么“使用命名空间标准”; considered a bad practice in C++? 在C ++中被认为是不好的做法? . I would recommend removing any using directives (which is probably the cause of this issue) and fully qualify everything. 我建议您删除所有using指令(这可能是导致此问题的原因)并完全限定所有条件。

when using <mutex> and have "using namespace std" 当使用<mutex>并具有“ using namespace std”时

use ::bind() instead of bind() 使用::bind()代替bind()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM