Reputation: 568
I'm trying to write a c++ program that uses classes, starts and listens for network connections, and then spins off a new thread for each new client.
Fortunately, I've figured out how to spawn a thread from inside a class, but when trying to do a accept() in the class I get a segmentation fault. I'll post the code to make it a little easier to show where I'm having issues.
#include <iostream>
#include <string.h> //for memset
#include <pthread>
#include <sys/types.h> //network
#include <sys/socket.h> //network
#include <netinet/in.h> //network
using namespace std;
class network
{
public:
void my_listen();
static void *handleClient(void * in_stream);
};
void* network::handleClient(void * in_stream)
{
int *stream = reinterpret_cast<int *>(in_stream);
write(*stream,"Hello Client\n", 12);
}
void network::my_listen()
{
/*
* Name: my_listen()
* Purpose: Listens and accepts new connections. Once accpeted, a new thread
* is spun off.
* Input: none
* Output: none
*/
int *new_socket_desc;
int port_num = 9876;
socklen_t client_addr_len;
int socket_desc = socket(AF_INET,SOCK_STREAM,0);
sockaddr_in serv_addr, cli_addr;
if(socket_desc == -1)
{
cerr << "Unable to create new sockets\n";
}
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(port_num);
if(bind(socket_desc, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
{
cerr << "Error on binding " << port_num << endl;
}
listen(socket_desc,5);
client_addr_len = sizeof(cli_addr);
pthread_t thread[10];
int count = 0;
*new_socket_desc = accept(socket_desc, (struct sockaddr *) &cli_addr, &client_addr_len); //Right here I segment fault
cout << "Connected client " << " @ " << new_socket_desc << " (" << *new_socket_desc << ")" << endl;
pthread_create(thread[0], handleClient, (void *)new_socket_desc);
pthread_join(thread[0],NULL);
}
Main isn't that exciting:
#include "network.h"
using namespace std;
int main()
{
network my_network;
my_network.my_listen();
}
What is interesting is that I can get all of this to work without using a class. I'm sure it has something to do with scope, but I don't know why.
By the way, I'm using gcc 4.6.2 with a target platform of x86_64
Upvotes: 1
Views: 397
Reputation: 7357
int *new_socket_desc;
// ....
*new_socket_desc = accept(socket_desc ....
You declaring new_socket_desc as a unitialized pointer, then assigning result of accept
to random memory location pointed by new_socket_desc
. So obviously this causes SEGFAULT. You should do:
int new_socket_desc;
// ....
new_socket_desc = accept(socket_desc ....
Upvotes: 1
Reputation: 14786
You declare new_socket_desc as a pointer but never set what it is pointing to. When you try to put a value at the location of the pointer (with the result of your accept call) it is writing to some random location in memory, which may or may not cause an immediate crash (in this version of your code it is causing a crash) but is always very bad.
Make new_socket_desc a regular int member of your class, use the & operator on it when creating the thread, and don't use the * operator on it otherwise, and you should have better luck.
Upvotes: 2