首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >OOP套接字不等待accept()

OOP套接字不等待accept()
EN

Stack Overflow用户
提问于 2011-08-08 22:09:02
回答 1查看 581关注 0票数 2

我们有一个以面向对象风格编写we服务器的练习。所以我们为WinSockets创建了一个类。我们希望循环主要部分(从accept到send)来逐个处理连接(只是为了启动;多线程将在稍后实现)。

问题:第一次建立连接时,一切都很好,但是服务器不会等待下一个连接接受。它说,它得到了一个连接,但描述符抛出了一个错误,errornr为"No Error“。

main:

代码语言:javascript
复制
NetInterface *socket;
#ifdef __unix__
    socket = new UnixSocket();
#elif __WIN32__ || _MSC_VER
    socket = new WinSocket();
#else 
    printf("Ihr System wird nicht Unterstützt");
#endif

socket->socketInit(PORT);

printf("server: waiting for connections...\n");
while(1) { // main accept() loop
    char *their_addr = socket->akzeptieren();
    if(their_addr == NULL)  {
        continue;
    }

    printf("server: got connection from %s\n", s);

    socket->empfangen();

    cout << socket->getInPacket() << endl;
}

WinSocket

代码语言:javascript
复制
class WinSocket : virtual public NetInterface
{
private:
    WSADATA wsaData;
    int iResult;

    SOCKET sockfd;
    SOCKET new_fd;

    struct addrinfo *servinfo;
    struct addrinfo hints;
    struct addrinfo *p;

    int iSendResult;
    string incoming;
    int recvbuflen;

    char s[INET6_ADDRSTRLEN];

    struct sockaddr_storage their_addr; // connector's address information
    socklen_t sin_size;

    int rv;

public:
    WinSocket();
    int socketInit(const char *port);
    char *akzeptieren();
    void empfangen();
    void senden(string s);
    string getInPacket();
    void *get_in_addr(struct sockaddr *sa);
};

[....]

char *WinSocket::akzeptieren(){
    sin_size = sizeof(their_addr);
    new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size);
    if (new_fd == INVALID_SOCKET) {
        perror("accept");
        return NULL;
    }
    inet_ntop(their_addr.ss_family, get_in_addr((struct sockaddr *)&their_addr), s, sizeof s);
    return s;       
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-08-08 22:18:33

我想你搞糊涂了。通常您应该有两个套接字:一个用于接受连接(您已经有了这个套接字)和一个用于交换数据(从调用WinSocket:akzeptieren()中的accept()返回为new_fd )。

在大多数框架中,侦听器套接字和流套接字之间有很大的区别:

代码语言:javascript
复制
// oversimplified interface.
class Listener 
{
public:
    Listener ( const std::string& host, const unsigned short port );
    Stream * accept ();
};

// oversimplified interface.
class Stream
{
public:
    const std::string peer () const;
    size_t send ( const void * data, size_t size );
    size_t recv (       void * data, size_t size );
};

因此,您的代码应该如下所示:

代码语言:javascript
复制
const std::string host = "127.0.0.1";
const unsigned short port = 1234;
Listener listener(host, port);
while ((stream = listener.accept())
{
    std::cout
        << "Connection from '" << stream->peer() << "'."
        << std::endl;
    stream->send("Hello, world!", 13);
    delete stream; // close and shutdown.
}

然后,您可以拥有:

代码语言:javascript
复制
class WinListener;
class WinStream;

并使整个过程成为多线程的。

注意::这似乎是一个要求(任务?),所以我不建议您做其他的事情。然而,在实际的生产系统中,这不是一个好的服务器设计。您可能最终想要阅读有关I/O completion portepollkqueue子系统的信息,以了解高效的异步I/O。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6983385

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档