Alright, my server only loops 3 times (recv's two strings that have been sent) and then freezes when there is no more information being recv'd. Note, this is happening in the listen() function.

Main.cpp

/* 
 * File:   main.cpp
 * Author: fellixombc
 *
 * Created on May 23, 2010, 2:14 PM
 */

#include <iostream>
#include "server.h"

using namespace std;

int main() {

    Server Server(6000);
    Server.Start();
    Server.Listen();

    return 0;
}

Server.cpp

/* 
 * File:   server.cpp
 * Author: fellixombc
 * 
 * Created on May 23, 2010, 2:17 PM
 */

#include "server.h"


/** Sets the needed info
 *  @param port to listen on
 */
Server::Server(int setport) {
    mPort = setport;
}

 /** Starts the server
  */
void Server::Start() {

    mSocket = socket(AF_INET, SOCK_STREAM, 0);
    cout << "Socket succesfully started." << endl;

    if (setsockopt(mSocket, SOL_SOCKET, SO_REUSEADDR, &mTrue, sizeof(int)) < 0) {
        cout << "ERROR" << endl;
    }

    server.sin_family = AF_INET;
    server.sin_port = htons(mPort);
    server.sin_addr.s_addr = INADDR_ANY;

    mSize = sizeof(server);

    if(bind(mSocket, (struct sockaddr*)(&server), mSize) < 0) {
        cout << "ERROR" << endl;
    }

    cout << "Starting server on port " << mPort << endl;
    cout << "LIVE" << endl;

}

 /** Listens to the incoming packets
  */
void Server::Listen() {

    listen(mSocket, 5);

    cout << "Listening." << endl;

    while(1) {

        const int size = 512;
        char buffer[size+1];
        int status;
        int flags;

        if(mConnectionPool.size() < 1) {

            mConnection = accept(mSocket, (struct sockaddr*)(&server), &mSize);
            mConnectionPool.push_back(mConnection);
            cout << "Connection handled and added." << endl;
            cout << "Size of connection pool: " << mConnectionPool.size() << endl;

        } else if(mConnectionPool.size() > 0) {

            cout << "Socket set to non blocking." << endl;
            flags = fcntl(mSocket, F_GETFL, 0);
            fcntl(mSocket, F_SETFL, flags | O_NONBLOCK);

            if(mConnection = accept(mSocket, (struct sockaddr*)(&server), &mSize) > 0) {
                mConnectionPool.push_back(mConnection);
                cout << "Connection handled and added." << endl;
                cout << "Size of connection pool: " << mConnectionPool.size() << endl;
            }

            cout << "Socket set to blocking." << endl;
            fcntl(mSocket, F_SETFL, flags & (~O_NONBLOCK));

            for(int i = 0; i < mConnectionPool.size(); i++) {
                cout << i << ": Looping" << mConnectionPool.size() << endl;
                if(status = read(mConnectionPool[i], buffer, size) > 0) {
                    cout << "Handle Message" << endl;
                    // handle message
                } else if(status == 0) {
                    cout << "0 bytes etc" << endl;
                    // handle
                } else if(status < 0) {
                    cout << "Reading error." << endl;
                    exit;
                }
            }

        }
                
    }
}

 /** Handles character packets
  *  @param Handle the desired character packet
  */
void Server::HandleCharPackets(char* packet) {

}

 /** Handles integer packets
  *  @param Handle the desired integer packet
  */
void Server::HandleIntPackets(int packet) {
    
}

Server.h

/* 
 * File:   server.h
 * Author: fellixombc
 *
 * Created on May 23, 2010, 2:17 PM
 */

#ifndef _SERVER_H
#define	_SERVER_H

#include <iostream>
#include <string>
#include <vector>
#include <string.h>
#include <cstdlib>

#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netdb.h>
#include <fcntl.h>

using namespace std;


class Server {
public:
    Server(int);
    void Start();
    void Listen();
    void HandleCharPackets(char*);
    void HandleIntPackets(int);

private:
    
    struct sockaddr_in server, client;

    int mPort;
    int mSocket;
    int mTrue;
    int mConnection;
    socklen_t mSize;

    vector<int> mConnectionPool;

};

#endif	/* _SERVER_H */

Recommended Answers

All 3 Replies

The sockets you 'accept' are set to blocking, which means they can wait indefinitely until new data is ready to be recv'd. So if you are only sending 2 strings on that socket, the loop will stick there if there is no data to be read.

I'm having trouble understanding why you check mConnectionPool.size() for < 1 or > 0, and then doing almost the same things, apart from setting non-blocking in one of the cases. But after this if-else you set the socket to blocking anyway.

So in the end the socket is always going to be set to blocking-mode.

The sockets you 'accept' are set to blocking, which means they can wait indefinitely until new data is ready to be recv'd. So if you are only sending 2 strings on that socket, the loop will stick there if there is no data to be read.

I'm having trouble understanding why you check mConnectionPool.size() for < 1 or > 0, and then doing almost the same things, apart from setting non-blocking in one of the cases. But after this if-else you set the socket to blocking anyway.

So in the end the socket is always going to be set to blocking-mode.

When a new connection joins, mConnectionPool.size is now 1, greater then 0. I have it so it waits and waits for a connection and then once it recv's a connection, it goes on through to normal loop where it recv's data.


Edit: I set the first socket to non-blocking, and the connection socket it handles, and that works perfectly, but when a new connection joins, it freezes >.>

void Server::Listen() {

    listen(mSocket, 5);

    cout << "Listening." << endl;

    while(1) {

        const int size = 512;
        char buffer[size+1];
        int status;
        int flags;

        if(mConnectionPool.size() < 1) {

            mConnection = accept(mSocket, (struct sockaddr*)(&server), &mSize);
            mConnectionPool.push_back(mConnection);
            cout << "Connection handled and added." << endl;
            cout << "Size of connection pool: " << mConnectionPool.size() << endl;
            flags = fcntl(mConnection, F_GETFL, 0);
            fcntl(mConnection, F_SETFL, flags | O_NONBLOCK);
            flags = fcntl(mSocket, F_GETFL, 0);
            fcntl(mSocket, F_SETFL, flags | O_NONBLOCK);

        } else if(mConnectionPool.size() > 0) {

            cout << "Socket set to non blocking." << endl;



            if(mConnection = accept(mSocket, (struct sockaddr*)(&server), &mSize)!= -1) {
                mConnectionPool.push_back(mConnection);
                cout << "Connection handled and added." << endl;
                cout << "Size of connection pool: " << mConnectionPool.size() << endl;
                flags = fcntl(mSocket, F_GETFL, 0);
                fcntl(mSocket, F_SETFL, flags | O_NONBLOCK);
            }

            for(int i = 0; i < mConnectionPool.size(); i++) {

                cout << i << ": Looping" << mConnectionPool.size() << endl;

                status = read(mConnectionPool[i], buffer, size);

                if(status > 0) {
                    cout << "Handling message: " << buffer << " dispatching to connection " << mConnectionPool[i] << endl;
                    int sentstat = send(mConnectionPool[i], &buffer, (socklen_t)sizeof(buffer), 0);
                    cout << sentstat << endl;

                } else if(status == 0) {
                    mConnectionPool.erase(mConnectionPool.begin(), mConnectionPool.begin() + i + 1);
                    // handle
                } else if(status < 0) {
                    cout << "Reading error." << endl;
                    exit;
                }
            }

        }
                
    }
}

Can anyone point me into the right direction? I just want to know why it blocks after another connection is accepted.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.