我不会发布所有通用套接字代码 - 除非请求,否则没问题。
我在已设置的套接字上侦听连接:
int
NetworkConnection::ListenForConnections()
{
char s[INET6_ADDRSTRLEN];
fcntl(socketFd, F_SETFL, O_NONBLOCK);
if (listen(socketFd, 15) == -1) {
perror("listen");
exit(1);
}
// sigAction.sa_handler = sigchld_handler; // reap all dead processes
// sigemptyset(&sigAction.sa_mask);
// sigAction.sa_flags = SA_RESTART;
if (sigaction(SIGCHLD, &sigAction, NULL) == -1) {
perror("sigaction");
exit(1);
}
printf("server: waiting for connections...\n");
sin_size = sizeof theirAddress;
int new_fd = accept(socketFd, (struct sockaddr *)&theirAddress, &sin_size);
if (new_fd == -1) {
perror("accept");
return 1;
}
inet_ntop(theirAddress.ss_family,
get_in_addr((struct sockaddr *)&theirAddress),
s, sizeof s);
printf("server: got connection from %s\n", s);
NodeConnection nc = NodeConnection();
char ipstr[INET6_ADDRSTRLEN];
getpeername(new_fd, (struct sockaddr*)&theirAddress, &sin_size);
struct sockaddr_in *soc = (struct sockaddr_in *)&theirAddress;
int port = ntohs(soc->sin_port);
inet_ntop(AF_INET, &soc->sin_addr, nc.ipstr, sizeof ipstr);
nc.fd = new_fd;
nc.theirAddress = sockaddr_storage(theirAddress);
nc.sin_size = sin_size;
nc.port = port;
newConnections.push_back(nc);
}
这是从这里调用的:
int main(int argc, const char* argv[])
{
RoutingManager *manager = new RoutingManager();
manager->ParseInputFile("topo.txt", 10, 3, " ");
manager->myConnection = new NetworkConnection("localhost", "7771");
manager->myConnection->SetSocketHints();
manager->myConnection->PopulateAddressInfo();
manager->myConnection->BindSocket();
while(1)
{
manager->myConnection->ListenForConnections(); // <- here
if (manager->myConnection->newConnections.size() > 0)
{
manager->ActivateNewNode();
}
}
}
在致电ActivateNewNode()
期间,我做了:
bool
RoutingManager::ActivateNewNode()
{
TopologyIter iter = topology.begin();
do
{
if(!iter->second.online)
{
iter->second.online = true;
iter->second.connection = myConnection->newConnections.back();
myConnection->newConnections.pop_back();
cout << "Connected Activated!\n";
cout << "Node ID: " << iter->second.id << endl;
return true; //all good
}
iter++;
}while (iter != topology.end());
return false; //received a connection, but no more nodes to hand out
}
connection
是结构:
struct NodeConnection
{
int fd;
socklen_t sin_size;
struct sockaddr_storage theirAddress;
char ipstr[INET6_ADDRSTRLEN];
int port;
};
如果我在调用ActivateNewNode()
期间注释掉连接的分配,这可以正常工作。即,这一行:
iter->second.connection = myConnection->newConnections.back();
但是,如果没有注释,那么当我循环回来继续侦听新连接时,此代码段会失败:
if (listen(socketFd, 15) == -1) {
perror("listen");
exit(1);
}
错误:bad file descriptor
谁能告诉我我在这里缺少什么?
答案 0 :(得分:1)
将listen()
放出while循环。