0

I am trying to create a simple local server that accepts connections on a different thread. I am trying to create a simple backup program for my files(kinda a like dumbed down cloud for my house). I have setup all the networking things in different classes. I am getting an error when i am trying to run accept on a different thread. I have not included the required includes here to save space and also have not completed my final code Right now I wanna make it working so that it can at least accept connections When I use the main server class's accept(down below) without thread it compiles but it doesn't work as expected it does not wait for a connection request it simply prints out -1 as fd. When i put it into a thread i get the following compiler error. Thank you for your time.

bipgen@genbox:~/Documents/College Projects/trans_lair$ g++ -std=c++11 server.cpp server_socket.cpp client.cpp
In file included from /usr/include/c++/5/thread:39:0,
                 from server.cpp:9:
/usr/include/c++/5/functional: In instantiation of ‘struct std::_Bind_simple<void (*(int))(Server&)>’:
/usr/include/c++/5/thread:137:59:   required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (&)(Server&); _Args = {int}]’
server.cpp:55:27:   required from here
/usr/include/c++/5/functional:1505:61: error: no type named ‘type’ in ‘class std::result_of<void (*(int))(Server&)>’
       typedef typename result_of<_Callable(_Args...)>::type result_type;
                                                             ^
/usr/include/c++/5/functional:1526:9: error: no type named ‘type’ in ‘class std::result_of<void (*(int))(Server&)>’
         _M_invoke(_Index_tuple<_Indices...>)

My classes are as follows:

#ifndef SERVER_SOCKET_H
#define SERVER_SOCKET_H
#endif
#include<sys/socket.h>

//Creating a simle server socket class

class Server_Socket
{
protected:
    int fd;
    struct addrinfo hints, *res;
    void setup_structure(int port);
    void setup_Socket();

public:
    Server_Socket(int port = 6666);
};

It's corresponding cpp file

/*
*It's implementioan
*
*/
#include "server_socket.h"

void Server_Socket :: setup_structure(int port)
{
   memset(&hints, 0 , sizeof hints);

   hints.ai_family = AF_UNSPEC;
   hints.ai_socktype = SOCK_STREAM;
   hints.ai_flags = AI_PASSIVE;

   int status;
   std::string s = std::to_string(port);
   char const *charPort = s.c_str();

   if( (status = getaddrinfo(NULL, charPort,&hints, &res)) != 0 )
   {
        //Throw something
   }
}

void Server_Socket :: setup_Socket()
{
    if(fd = socket(res->ai_family,res->ai_socktype,res->ai_protocol ) < 0 )
    {
        //Throw something
    }
}

Server_Socket :: Server_Socket(int port)
{
    setup_structure(port);
    setup_Socket();
}

A class to hold clients and its methods

#ifndef CLIENT_H
#define CLIENT_H
#endif

#include<sys/types.h>
#include<sys/socket.h>

class Client
{
    protected:
    int fd;

    public:
    Client(int &fd);
    int Read(char* buffer);
    int Write(char* buffer);
};

It's cpp file

#include "client.h"

using namespace std;

Client :: Client(int &fd)
{
    this->fd = fd;
}

int Client :: Read(char* buffer)
{
    int status;
    status = read(fd,buffer,0);
    if( status < 0 )
    {
        //Throw Something
    }
    return status;
}

int Client :: Write(char* buffer)
{
    int status;
     status = send(fd ,buffer, sizeof(buffer),0);
    if( status < 0 )
    {
        //Throw something
    }
    return status;
}

Finally the server class the main class

#include "server_socket.h"
#include<vector>
#include <mutex>
#include "client.h"

class Server : public Server_Socket
{
    protected:
    std::vector <Client> conn_list;
    fd_set readset;
    fd_set writeset;

    public:
    Server(int port = 6667,int backlog = 20);

    friend void Accept(Server &a);
};

It's main cpp file

#include "server.h"

using namespace std;

Server :: Server(int port,int backlog) : Server_Socket(port)
{
    //Bind local socket
    bind(fd,res->ai_addr,res->ai_protocol);

    //Listen local socket
    listen(fd, backlog);
    cout<<"Server initialized at port: "<<port<<endl;
}
std :: mutex m;

void  Accept(Server &a)
{
    struct sockaddr client;
    socklen_t client_size;

    while(1)
    {
        int new_conn_fd = accept(a.fd,&client,&client_size);
        if( new_conn_fd < 0 )
        {
            //Throw Something
        }
       // m.lock();
        Client s(new_conn_fd);
        a.conn_list.push_back(new_conn_fd);
        cout<<"Accepted: "<<new_conn_fd;
       // m.unlock();

    }
}


int main()
{
    Server s;
    //Accept(s); compiles but does prints -1 infinitely
    std::thread t(Accept,5); //does not compile
    if(t.joinable())
    t.join();
}
Bipul Adh
  • 103
  • 1
  • 2
  • 6
  • 1
    Dealing with native sockets is very nasty. I recommend that you use some higher level socket, such as `Boost.ASIO`. – The Quantum Physicist Mar 28 '17 at 13:40
  • This code is all so very wrong. If you want to code the sockets yourself, get the basics working before layering multiple classes on top. Log the values you get. Handle errors. Even if you choose to use Boost.ASIO (which would be a good idea), write a simple proof-of-concept before a load of broken classes. – Useless Mar 28 '17 at 13:55
  • I assume `t(Accept, 5)` does not compile because 5 is not a valid parameter to the Accept function. I'm pretty sure you are mixing the client and server side here. accept function does not create a client but rather a server side object that handles that specific connection. I would also suggest using composition instead of inheritance, i.e. make the Server object contain the socket object and not inherit it. As for the -1 print, you should debug your code and see why it is printing this. – o_weisman Mar 28 '17 at 13:59
  • Given `int Client :: Write(char* buffer)`, what do you think `sizeof( buffer )` returns? – Andrew Henle Mar 28 '17 at 14:35
  • the length of buffer. but i feel like i am wrong. btw that 5 is just a typo same error with s. – Bipul Adh Mar 28 '17 at 15:00

0 Answers0