Вот мой код:
void error(const char *msg)
{
perror(msg);
exit(1);
}
void sServer::acceptClientConnections(int listenerSocket)
{
struct sockaddr clientAddress;
socklen_t sizeOfClientAddress = sizeof(clientAddress);
while (true)
{
int newConnection = accept(listenerSocket, &clientAddress, &sizeOfClientAddress);
std::cout << "Someone connected ... " <<std::endl;
liveConnections.push_back(newConnection);
}
}
int sServer::getServerListenerSocket()
{
return serverListenerSocket;
}
sServer::sServer(int port)
{
int serverListenerSocket;
struct sockaddr_in serv_addr;
serverListenerSocket = socket(AF_INET, SOCK_STREAM, 0);
if (serverListenerSocket < 0)
error("ERROR opening a socket. Cannot start sever. Exiting ...");
memset((char *) &serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(port);
std::cout << "Host ip: " << serv_addr.sin_addr.s_addr << "\n";
if ( bind(serverListenerSocket, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0 )
error("ERROR on binding server socket. Are you running another instance of this server ?");
listen(serverListenerSocket, 45);
}
Вызывается следующим образом:
int main()
{
sServer superServer(9889);
std::thread handleConnections( &sServer::acceptClientConnections, superServer, superServer.getServerListenerSocket() );
}
Я ожидал, что я буду ждать входящих соединений, и когда соединение вступит в силу, начните действовать.
Но вместо этого, когда я запускаю программу, она непрерывно печатает "Кто-то подключен...", даже если соединения не выполняются.
По иронии судьбы, если я начинаю поток в конце конструктора, он работает хорошо.
Не могли бы вы объяснить, почему это происходит и каков был бы правильный способ принять соединение?
Теперь, когда мы определили ошибку, проблема заключается в локальной переменной в конструкторе:
sServer::sServer(int port)
{
int serverListenerSocket;
Просто удалите его. Он затеняет член класса с тем же именем, поэтому последний никогда не устанавливается, поэтому accept()
получает EBADF,
возвращая -1, никогда не отображая принятое соединение, не куря CPU и т.д.
Причина, по которой она работает при запуске потока внутри конструктора, заключается в том, что локальная переменная все еще находится в области видимости.
accept
. Держу пари, это-1
.