gpt4 book ai didi

c++ - OOP 套接字不等待 accept()

转载 作者:塔克拉玛干 更新时间:2023-11-03 06:57:55 24 4
gpt4 key购买 nike

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

问题:第一次建立连接时一切正常,但随后,服务器不会等待下一个连接接受。它说,它获得了一个连接,但是该描述符抛出一个错误,errornr 为“No Error”。

主要内容:

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

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

最佳答案

我觉得你很困惑。你通常应该有 2 个套接字:1 个用于接受连接(你已经有这个)和 1 个用于交换数据(返回 new_fd 从调用 accept()WinSocket:akzeptieren()).

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

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

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

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.
}

然后,你可以:

class WinListener;
class WinStream;

并使整个事情成为多线程。

注意:这似乎是一项要求(作业?),所以我不建议您不这样做。然而,在实际的生产系统中,这并不是一个好的服务器设计。您可能最终想阅读有关 I/O completion port 的信息, epollkqueue用于高效异步 I/O 的子系统。

关于c++ - OOP 套接字不等待 accept(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6983385/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com