Alright, so everything works, except there are a couple minor bugs. Also, is there a more efficient way in doing my listen method? Thanks.

Bugs:
-First client does not recv the information it sent, until the 2nd client connects. (the server sends it back)
-Everyother click recv's everything twice.

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 = 0;

        mConnection = accept(mSocket, (struct sockaddr*)(&client), &mSize);

        mConnectionPool.push_back(mConnection);

        cout << "Handling connection " << mConnection << endl;

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

            cout << mConnectionPool[i] << endl;

            cout << mConnectionPool.size() << endl;

            int flags = fcntl(mConnectionPool[i], F_GETFL, 0);
            fcntl(mConnectionPool[i], F_SETFL, flags | O_NONBLOCK);

            do {

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

                cout << status << endl;

                if(status == 0) {

                    mConnectionPool.erase(mConnectionPool.begin() + i);
                    cout << "Connection " << mConnectionPool[i] << " was erased, reason: disconnection." << endl;
                    
                } else {
                    
                    buffer[size] = '\0';
                    cout << "Msg Recv'd:" << buffer << endl;

                    send(mConnectionPool[i], buffer, strlen(buffer), 0);
                    cout << "Wrote to Client: " << buffer << endl << "With the size of: " << strlen(buffer) << endl;

                } 
            } while(status != -1);
        }
    }
}

 /** 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 */

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;
}

Recommended Answers

All 4 Replies

On line 58 of your server.cpp, you are hanging on the "accept" call. That is, first time through, you accept the connection from your first client. It's running through your loop below, but there's no data, so it goes back to the top and hits the "accept" again, waiting for another connection. Only after the second client connects do you go through the loop, check the input and send the response back to the first client.

You will need to use a multiplexing function like "select" to check the readability of the sockets (including the "server" socket) so you don't hang on inbound connections. You will instead use the select function to test the sockets (you pass in an array of socket handles), and the return from the select call will indicate which handles are ready for reading (or accepting). This way, you can service data from connected clients without having to have new connections kick you off the accept call.

The GNU site has an example of a C/C++ socket server that uses select:

http://www.gnu.org/s/libc/manual/html_node/Server-Example.html#Server-Example

Alright, thank you for posting. I think that pretty much solves it.

Oooh, thank you too ketsuekiame! And yes, I do google most things, but when I cannot find a solution, I finally come here.

anyways, solved.

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.