接受线程 C++ 套接字中的函数循环



>我有两个问题:

首先 - 我每次尝试将一个客户端连接到服务器。(接受函数在线程中(,但连接在接受中失败 - 始终返回 -1(而不是零(。

第二个问题 - 如何为接受客户端添加超时?

服务器.h

class Server{
public:
void open(int port, object&);
void startThreadOPeration();
void stop(){};
~Server();
private:
sockaddr_in address;
int socketfd;
Object* obj; 
void startThread();
std::thread acceptClient;
};

服务器.cpp

void Server::open(int port,Object& obj) {
this->obj = &obj;
int socketfd = socket(AF_INET, SOCK_STREAM, 0);
if (socketfd == -1) {
throw "Could not create a socket";
}
this->socketfd = socketfd;
sockaddr_in address;
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY; 
address.sin_port = htons(port);
this->address = address;
if (bind(socketfd, (struct sockaddr *) &this->address, sizeof(this->address)) == -1) {
throw "Could not bind the socket to an IP";
}

if (listen(this->socketfd, 5) == -1) { 
throw "Error during listening command";
} else {
std::cout<<"Server is now listening ..."<<std::endl;
}

startThread();
}

void Server::startThreadOPeration() {
while (!side_server::stop) {
// accepting a client
int client_socket = accept(this->socketfd, (struct sockaddr *) &this->address,
(socklen_t *) &this->address); // Return -1
if (client_socket == -1) {
throw "Error accepting client";
}
//do operation
}

void Server::startThread() {

acceptClient = std::thread(&Server::startThreadOPeration,this);
}
Server::~Server(){
close(this->socketfd);
if(acceptClient.joinable()){
this->acceptClient.join();
}
}

谢谢你的帮助!

accept()

接受 3 个参数 - 套接字、指向套接字地址结构的指针和指向包含给定套接字地址结构最大长度的socklen_t的指针。 成功后,socklen_t将使用套接字结构的实际长度进行更新。

遗憾的是,您的代码使用 3rd 参数中this->address变量的地址而不是有效socklen_t变量的地址调用accept()。 很有可能,这会导致this->address在更新它认为是socklen_t但实际上不是时包含看起来完全是胡说八道的内容accept()

void Server::startThreadOPeration() {
while (!side_server::stop) {
// accepting a client
socklen_t len = sizeof(this->address); // max size of address structure
int client_socket = accept(this->socketfd, 
(struct sockaddr *) &this->address, 
&tlen); // supply valid max length
if (client_socket == -1) {
throw "Error accepting client";
}
//do operation
}

accept()不容易超时,但select()可以:

void Server::startThreadOPeration() {
while (!side_server::stop) {
fd_set readfds;
struct timeval tv;
int result;
FD_ZERO(&readfds);
tv.tv_sec = timeout_s; // number of seconds to wait here
tv.tv_usec = timeout_us; // number of additional us to wait here
FD_SET(this->socketfd, &readfds);
result = select(this->socketfd + 1, &readfds, NULL, NULL, &tv);
if (result > 0) 
{
// cheating a bit here since the only thing in readfds will be this->socketfd
// normally you should check what of many file descriptors is set.
socklen_t len = sizeof(this->address);
int client_socket = accept(this->socketfd, 
(struct sockaddr *) &this->address, 
&tlen); // supply valid max length
if (client_socket == -1) {
throw "Error accepting client";
}
//do operation
}
else
{
// handle any failure except timeout here 
}
}
}

相关内容

  • 没有找到相关文章

最新更新