I having issues creating an echo program using socket programming. I do not have any error coded appear when I run the socket(), bind(), and listen() command. All of them return an integer, value 3. The part that is causing the issue in the accept() command. To test this program, I have ran the executable as a background process and run telnet to test the socket connection. The program is freezing at the accept() command. Can anyone help?
// Include all of the headers required
#include "echo_s.h"
// simple logger
#include "log.h"
// ***
// Class ClientConnection
// - created to help simply methods and functions used to create TCP connection
// for this program to work
class ClientConnection {
public:
void createSocket();
void setupAddress();
void bindSocket();
void listenSocket();
void waitingConnection();
int processConnection(int connection);
private:
int sock = -1; // file descriptor for the server
int lst = -1; // file descriptor for the listener
struct sockaddr_in
{
short family; // address family
u_short port; // port number
struct in_addr sin_addr; // internet address
char sin_zero[8];
};
struct sockaddr_in servAddr; // struct needed for the server addr
struct sockaddr_in clientAddr; // struct needed for the listener addr
char buffer[256];
};
Log* logger = new Log();
// ***
// main ()
// - sets up the socket and accepts new connection until CLOSE or QUIT
int main (int argc, char *argv[])
{
// Process the command arguments
int opt = 0;
ClientConnection client;
while ((opt = getopt(argc, argv, "v")) != -1)
{
switch (opt)
{
case 'v':
logger->setLogger(true);
logger->printLog("Verbose Action captured");
break;
case ':':
case '?':
default:
std::cout<< "Invalid option: " << argv[0] << std::endl;
exit(-1);
}
}
// create the socket
client.createSocket();
// set up socket address
client.setupAddress();
// bind socket
client.bindSocket();
// listen socket
client.listenSocket();
// Wait for the connection with the accept call
client.waitingConnection();
}
void ClientConnection::createSocket ()
{
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
logger->printLog ("Error opening socket");
exit (-1);
}
else
{
logger->printLog("Socket was created");
logger->printLog("Socket info: " + std::to_string(sock));
}
}
void ClientConnection::setupAddress ()
{
// define the struct
srand(time(NULL));
int port = (rand() % 10000 + 1024);
// zero the whole struct
bzero((char *)&servAddr, sizeof(servAddr));
// Fill in the struct with the information need for the address of the host
servAddr.family = AF_INET;
servAddr.sin_addr.s_addr = INADDR_ANY;
servAddr.port = htons(port);
logger->printLog("Address has been created for socket");
}
void ClientConnection::bindSocket ()
{
int bindSuccess = 0;
int attempts = 0;
std::string errorString;
if (bind(sock, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0)
{
errorString = strerror(errno);
logger->printLog("bind() failed: " + errorString);
exit(-1);
}
else
{
logger->printLog("bind() successful");
logger->printLog("Bind() function returned: " + std::to_string(sock));
std::cout << "Port number: " << servAddr.port << std::endl;
}
}
void ClientConnection::listenSocket ()
{
int listenSocket = 5;
std::string errorString;
if (listen(sock, listenSocket) < 0)
{
errorString = strerror(errno);
logger->printLog("listen() failed: " + errorString);
exit(-1);
}
else
{
logger->printLog("listen() successful");
logger->printLog("listen() fucntion returns: " + std::to_string(sock));
}
}
void ClientConnection::waitingConnection ()
{
logger->printLog("Attempting accept()");
int quit = -1;
int attempts = 0;
socklen_t sizeClient = sizeof(clientAddr);
while(quit == -1)
{
logger->printLog("Inside while loop");
//lst = accept(sock, (struct sockaddr *) &servAddr, sizeof(servAddr));
lst = accept(sock, (struct sockaddr *) NULL, NULL);
logger->printLog("accept() function reurns: " + std::to_string(lst));
if (lst < 0)
{
std::string errorString = strerror(errno);
logger->printLog(errorString);
attempts++;
exit(-1);
}
else
{
logger->printLog("accept() successful");
quit = processConnection(lst);
}
}
}
int ClientConnection::processConnection(int connection)
{
std::cout << "connection made. TEST" << std::endl;
int n = 0;
if ((n = read(connection, buffer, 255)) < 0)
{
logger->printLog("Error reading data");
}
else
{
std::string message = buffer;
logger->printLog(message);
if (message.find("QUIT"))
{
close(connection);
return 1;
}
if (message.find("CLOSE"))
{
close(connection);
return 0;
}
n = write(connection, buffer, sizeof(buffer));
}
return 0;
}
`
Related
I want to create two projects with this code so that they can chat with each other, but no matter how much I send, the data does not reach the other client.
I've been thinking and trying for hours on this problem, but it doesn't work. Various multicast chat programs on the web are written in languages other than C++, some use threads and some do not. To the best of my knowledge right now, I can't understand the codes on the web.
For fear of lengthy code, the basic header file and error output function have been omitted.
// header file and function declaration
#define MAXBUF 80
SOCKADDR_IN maddr;
int main(int argc, char* argv[]) {
int port;
cout << "input port number" << endl;
cin >> port;
cout << "use port : " << port << endl;
WSADATA wsa;
if (WSAStartup(MAKEWORD(2, 2), &wsa))
{
err_display("WSAStartup");
return -1;
}
//create send socket
SOCKET r_sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (r_sock == INVALID_SOCKET)
{
err_display(" recv socket");
return -1;
}
//create recv socket
SOCKET s_sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (s_sock == INVALID_SOCKET)
{
err_display(" send socket");
return -1;
}
// bind
maddr.sin_family = AF_INET;
maddr.sin_port = htons(port);
maddr.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(r_sock, (SOCKADDR*)&maddr, sizeof(maddr))) {
err_display("bind");
return -1;
}
// Join the Multicast address
const char* mip = "236.0.0.1";
IP_MREQ mreq;
mreq.imr_interface.s_addr = htonl(INADDR_ANY); // s_addr = 주소
// Setting Multicast address
if (!(inet_pton(AF_INET, mip, &mreq.imr_multiaddr))) {
err_display("inet_pton");
return -1;
}
// JOIN
if (setsockopt(r_sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&mreq, sizeof(mreq))) {
err_display("setsockopt");
return -1;
}
while (true) {
HANDLE h1 = (HANDLE)_beginthreadex(NULL, 0, &sendf, (LPVOID)s_sock, 0, NULL);
HANDLE h2 = (HANDLE)_beginthreadex(NULL, 0, &recvf, (LPVOID)r_sock, 0, NULL);
}
closesocket(r_sock);
closesocket(s_sock);
WSACleanup();
return 0;
}
unsigned __stdcall sendf(LPVOID arg) // send thread function
{
SOCKET s_sock = (SOCKET)arg;
char mesbuf[MAXBUF];
int sendlen;
while (1)
{
// send
char mesbuf[MAXBUF];
if (fgets(mesbuf, MAXBUF - 1, stdin) == NULL)
break;
cout << "send Thread" << endl;
sendlen = strlen(mesbuf);
sendto(s_sock, mesbuf, sendlen, 0, (SOCKADDR*)&maddr, sizeof(maddr));
}
return 0;
}
unsigned __stdcall recvf(LPVOID arg) // recv thread function
{
SOCKADDR_IN paddr; // peer address
int namelen = sizeof(paddr);
SOCKET r_sock = (SOCKET)arg;
char mesbuf[MAXBUF];
int recvlen;
while (1)
{
char mesbuf[MAXBUF];
//recive
recvlen = recvfrom(r_sock, mesbuf, MAXBUF - 1, 0, (SOCKADDR*)&paddr, &namelen);
cout << "recv Thread" << endl;
if (recvlen == SOCKET_ERROR) {
err_display("recv error");
closesocket(r_sock);
break;
}
if (recvlen == 0)
{
cout << "normal close connection case" << endl;
closesocket(r_sock);
break;
}
mesbuf[recvlen] = '\0'; // string conversion
cout << "from : " << mesbuf << endl;
}
return 0;
}
I have been trying to understand why on my server the accept() call is still blocking when the client has a successful connect() call?
server.cpp
#include <errno.h>
#include <strings.h>
#include <iostream>
#include "globals.h"
using namespace std;
/* Declaring errno */
extern int errno;
/* Function for printing error */
void report_error(char *s)
{
printf("receiver: error in%s, errno = %d\n", s, errno);
exit(1);
}
int main(int argc, char *argv[])
{
int s,c;
int res;
struct sockaddr_in socket_address = {0}, client_sa = {0};
unsigned int client_sa_len = sizeof(client_sa);
/* Creating the socket and returns error if unsuccesfull */
if((s= socket(AF_INET, SOCK_DGRAM, PF_UNSPEC)) == -1)
report_error("socket");
socket_address.sin_family = AF_INET;
socket_address.sin_addr.s_addr=INADDR_ANY;
socket_address.sin_port = htons(5318 + 2000);
/* Binding the socket and returns error if unsuccesfull */
if(bind(s, (struct sockaddr *)&socket_address, sizeof(socket_address))== -1)
report_error("bind");
listen(s, 10);
cout << "listening on port\n";
while(1)
{
/*The server just hangs here*/
c = accept(s, (struct sockaddr*)&client_sa, &client_sa_len);
if (c > 0)
{
cout << "LOG: Was the accept successful" << endl;
res = fork();
if (res < 0)
{
perror("Forking of child failed");
}
}
if(res == 0)
{
//close(s);
char msg[MSGL], reply[50], args[MSGL];
char command[MSGL];
cout << "LOG: Get message?" << endl;
GetRequest(msg, c, &client_sa);
if( (msg[0] == 'c') && (msg[1] == 'd') && (msg[2] == ' '))
{
strncpy(command, "cd", sizeof(command));
int arg_i = 0;
for(int i = 3; msg[i] != '\n'; ++i)
{
args[arg_i] = msg[i];
++arg_i;
}
}
else
{
for(int i = 0; msg[i] != '\n'; ++i)
{
command[i] = msg[i];
}
}
else
{
if(c > 0)
{
//close(c);
}
}
}
return 0;
}
When I run this server it prints that it is listening, then when I initialize the client it does not say that the client has connected
client.cpp
#include <errno.h>
#include <arpa/inet.h>
#include <iostream>
#include <string>
#include "globals.h"
using namespace std;
/* Declaring errno */
extern int errno;
int main(int argc, char *argv[])
{
int s;
char* server_address = argv[1];
char command[MSGL];
char reply[MSGL];
int connect_success;
struct sockaddr_in sa = {0} ,cli_sa = {0};
int length = sizeof(sa);
struct hostent *hp;
cli_sa.sin_family = AF_INET;
cli_sa.sin_addr.s_addr=INADDR_ANY;
cli_sa.sin_port = htons(5318 + 2001);
/* FILL SOCKET ADDRESS*/
if((hp = gethostbyname(server_address))==NULL)
report_error("gethostbyname");
bcopy((char*)hp->h_addr, (char *)&sa.sin_addr, hp->h_length);
sa.sin_family = hp->h_addrtype;
//memcpy(&sa.sin_addr, hp->h_addr, hp->h_length);
sa.sin_port = htons(5318 + 2000); /* define port number based on student ID*/
/* Creating the socket and returns error if unsuccessfull */
if((s=socket(AF_INET, SOCK_DGRAM, PF_UNSPEC))== -1)
report_error("socket");
/* Binding the socket and returns error if unsuccesfull */
if(bind(s, (struct sockaddr *)&cli_sa, sizeof(cli_sa))== -1)
report_error("bind");
connect_success = connect(s,(struct sockaddr*) &sa, length);
cout << connect_success << endl;
if (connect_success < 0)
{
report_error("connect");
cout << "LOG: is there an error?" << endl;
}
cout << "LOG: is the connection made?" << endl;
while(1)
{
cout << "myRPC>>";
fgets(command,MSGL,stdin);
if (DoOperation(command,reply,s,sa) == SEND_FAILURE)
{
cout << "Error: sending command\n";
}
}
return 0;
}
I'm fairly certain that your server process has undefined behavior.
accept() and connect() is for TCP sockets. You are creating UDP sockets. For UDP sockets, all that connect() does is set the default address for send(), and it always succeeds immediately. This is explained in the manual page for connect(2), which you should definitely read:
If the socket sockfd is of type SOCK_DGRAM, then addr is the address
to which datagrams are sent by default, and the only address from
which datagrams are received.
I expect accept() to fail for UDP (SOCK_DGRAM) sockets, most likely with EINVAL. If you review the logic in your server code, when accept() fails, res never gets initialized before its value is tested in the if() statement.
Undefined behavior.
I want to make a server and client program with TCP protocol using C++. The server must be able to handle multiple client at once. But the problem is for example, after starting the server, I run 2 clients with the server 's IP address and port as parameters. Next, both clients are sending data to server. At first, both clients could send data to server and the server was able read the data. But, once the server has received data from the second client, it seems that it stopped receiving from the first client. Do you have any solution?
Here is the server code
using namespace std;
void *task1(void *);
static int connFd;
void error(const char *msg)
{
perror(msg);
exit(1);
}
int main(int argc, char* argv[])
{
int pId, portNo, listenFd;
socklen_t len; //store size of the address
bool loop = false;
struct sockaddr_in svrAdd, clntAdd;
pthread_t threadA[3];
if (argc < 2)
{
cerr << "Syntam : ./server <port>" << endl;
return 0;
}
portNo = atoi(argv[1]);
if((portNo > 65535) || (portNo < 2000))
{
cerr << "Please enter a port number between 2000 - 65535" << endl;
return 0;
}
//create socket
listenFd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if(listenFd < 0)
{
cerr << "Cannot open socket" << endl;
return 0;
}
bzero((char*) &svrAdd, sizeof(svrAdd));
svrAdd.sin_family = AF_INET;
svrAdd.sin_addr.s_addr = INADDR_ANY;
svrAdd.sin_port = htons(portNo);
//bind socket
if(bind(listenFd, (struct sockaddr *)&svrAdd, sizeof(svrAdd)) < 0)
{
cerr << "Cannot bind" << endl;
return 0;
}
listen(listenFd, 5);
int noThread = 0;
while (noThread < 3)
{
socklen_t len = sizeof(clntAdd);
cout << "Listening" << endl;
//this is where client connects. svr will hang in this mode until client conn
connFd = accept(listenFd, (struct sockaddr *)&clntAdd, &len);
if (connFd < 0)
{
cerr << "Cannot accept connection" << endl;
return 0;
}
else
{
cout << "Connection successful" << endl;
}
pthread_create(&threadA[noThread], NULL, task1, NULL);
noThread++;
}
for(int i = 0; i < 3; i++)
{
pthread_join(threadA[i], NULL);
}
}
void *task1 (void *dummyPt)
{
cout << "Thread No: " << pthread_self() << endl;
char test[256];
bzero(test, 256);
bool loop = false;
while(!loop)
{
bzero(test, 256);
int n = read(connFd, test, 255);
if (n < 0) error("ERROR reading from socket");
printf("Here is the message: %s\n",test);
}
cout << "\nClosing thread and conn" << endl;
close(connFd);
}
And the client code
using namespace std;
int main (int argc, char* argv[])
{
int listenFd, portNo;
bool loop = false;
struct sockaddr_in svrAdd;
struct hostent *server;
if(argc < 3)
{
cerr<<"Syntax : ./client <host name> <port>"<<endl;
return 0;
}
portNo = atoi(argv[2]);
if((portNo > 65535) || (portNo < 2000))
{
cerr<<"Please enter port number between 2000 - 65535"<<endl;
return 0;
}
//create client skt
listenFd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if(listenFd < 0)
{
cerr << "Cannot open socket" << endl;
return 0;
}
server = gethostbyname(argv[1]);
if(server == NULL)
{
cerr << "Host does not exist" << endl;
return 0;
}
bzero((char *) &svrAdd, sizeof(svrAdd));
svrAdd.sin_family = AF_INET;
bcopy((char *) server -> h_addr, (char *) &svrAdd.sin_addr.s_addr, server -> h_length);
svrAdd.sin_port = htons(portNo);
int checker = connect(listenFd,(struct sockaddr *) &svrAdd, sizeof(svrAdd));
if (checker < 0)
{
cerr << "Cannot connect!" << endl;
return 0;
}
//send stuff to server
for(;;)
{
char s[300];
//cin.clear();
//cin.ignore(256, '\n');
cout << "Enter stuff: ";
bzero(s, 300);
cin.getline(s, 300);
write(listenFd, s, strlen(s));
}
}
Yor connFd is a global variable, which you access from your main thread and all handling threads. This will not do! Imagine that - you've accepted the first connection and set the variable to the receiving socket. You've spawn the handling thread, which started reading. Next thing you know, another connection is coming along and you are receiving it as well! This very moment connFd points to the new connection, so the thread which is already using it will suddenly switch to the new connection! Of course it is not good.
The way to fix this problem is to pass the connection to the thread in such a way that is is not shared across threads. And easiest way of doing so is to use C++ thread class.
For example, this is code fragment illustrating the above idea:
void handle_connection(int fd) {
... <your task1 code>
}
...
std::vector<std::thread> threads;
...
int conn = accept(listenFd, (struct sockaddr *)&clntAdd, &len);
threads.push_back(std::thread(&handle_connection, conn));
...
... (in the end)
for (auto&& t : threads)
t.join();
I made a small socket echo server with a blocking socket (see code below), but the select statement always returns 0 even when there is a message to be read. Everything else works. If you replace the select statement by simple assigning 1 to selectResult, the server works.
The server runs on Ubuntu in a VM, while the client is on the Host system (Windows 7 professional). My IDE for the server is Eclipse 3.8 and it uses OpenSSL 1.0.1j.
To get this code to work, you only need to include OpenSSL's root directory, add its library path to the linker and link to ssl, crypto and dl (in that order). Also you need a certificate and private key.
Thanks in advance!
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <sys/socket.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <iostream>
using namespace std;
#define MAX_BUFFER 1024
int main()
{
// Initializing...
SSL_CTX*_ctx = NULL;
SSL* _ssl = NULL;
fd_set _fdSet;
int _serverSocket = 0;
int _port = 9090;
timeval t;
const char* certPath = "/home/alex/Certificate/cacert.pem";
const char* pKeyPath = "/home/alex/Certificate/privkey.pem";
// Init OpenSSL
SSL_library_init();
SSL_load_error_strings();
OpenSSL_add_all_algorithms();
_ctx = SSL_CTX_new(TLSv1_1_server_method());
if (_ctx == NULL)
{
ERR_print_errors_fp(stderr);
abort();
}
// Set certificate and private key.
if (SSL_CTX_use_certificate_file(_ctx, certPath, SSL_FILETYPE_PEM) <= 0)
{
ERR_print_errors_fp(stderr);
abort();
}
if (SSL_CTX_use_PrivateKey_file(_ctx, pKeyPath, SSL_FILETYPE_PEM) <= 0)
{
ERR_print_errors_fp(stderr);
abort();
}
if (!SSL_CTX_check_private_key(_ctx))
{
fprintf(stderr, "Private key does not match the public certificate\n");
abort();
}
// Initialize server socket:
// 1. set address
struct sockaddr_in addr;
int optval = 1;
bzero(&addr, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(_port);
addr.sin_addr.s_addr = INADDR_ANY;
// 2. init socket, set socket options, bind it to address
_serverSocket = socket(PF_INET, SOCK_STREAM, 0);
setsockopt(_serverSocket, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
if (bind(_serverSocket, (struct sockaddr*) &addr, sizeof(addr)) != 0)
{
perror("can't bind port");
abort();
}
// 3. Prepare the socket to accept connections
if (listen(_serverSocket, 1) != 0)
{
perror("Can't configure listening port");
abort();
}
cout << "Server finished initializing." << endl;
bool bServerStayAlive = true;
while (bServerStayAlive)
{
cout << "Waiting for connection..." << endl;
struct sockaddr_in addr;
unsigned int len = sizeof(addr);
int client = accept(_serverSocket, (struct sockaddr*) &addr, &len);
printf("Connection: %s:%d\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
_ssl = SSL_new(_ctx);
SSL_set_fd(_ssl, client);
if (SSL_accept(_ssl) == -1) /* do SSL-protocol accept */
ERR_print_errors_fp(stderr);
else
{
while (bServerStayAlive)
{
FD_ZERO(&_fdSet);
FD_SET(_serverSocket, &_fdSet);
t.tv_sec = 1;
t.tv_usec = 0;
int selectResult = select(_serverSocket + 1, &_fdSet, NULL, NULL, &t);
if (selectResult == 0)
{
cout << "timeout" << endl;
continue;
}
if (selectResult < 0)
{
cout << "Select error: " << selectResult << endl;
bServerStayAlive = false;
break;
}
cout << "Going to read something\n";
unsigned char buffer[MAX_BUFFER];
memset(buffer, 0, MAX_BUFFER);
int bytes = SSL_read(_ssl, buffer, MAX_BUFFER); /* get request */
if (bytes > 0)
{
cout << "Received message: " << endl;
for (int i = 0; i < bytes; i++)
cout << buffer[i];
cout << endl;
SSL_write(_ssl, buffer, bytes);
}
else
{
ERR_print_errors_fp(stderr);
break;
}
}
}
int sd = SSL_get_fd(_ssl); /* get socket connection */
SSL_free(_ssl); /* release SSL state */
close(sd); /* close connection */
cout << "Connection was closed.\n";
}
// Uninitializing
close(_serverSocket);
SSL_CTX_free(_ctx);
return 0;
}
I think you meant to select on the client socket that you just accepted, not the _serverSocket that you're accepting connections on.
I won't post all of the generic socket-code -- unless requested, then no problem.
I listen for connections on an already setup socket:
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);
}
This is called from here:
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();
}
}
}
And during the call to ActivateNewNode() I do:
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
}
Where connection is the struct:
struct NodeConnection
{
int fd;
socklen_t sin_size;
struct sockaddr_storage theirAddress;
char ipstr[INET6_ADDRSTRLEN];
int port;
};
This works fine if I comment out the assignment of the connection during the call to ActivateNewNode(). I.e., this line:
iter->second.connection = myConnection->newConnections.back();
However, with it uncommented, then when I loop back through to continue listening for new connections, this snippet fails:
if (listen(socketFd, 15) == -1) {
perror("listen");
exit(1);
}
With the error: bad file descriptor
Can anyone tell me what I'm missing here?
put the listen() out of the while loop.