Hi,
I am trying to encapsulate Linux sockets and POSIX threads in C++ classes (I work in Knoppix, using KDevelop). Since sockets and threads are new to me, I searched for example code and found the following:
This is C code, but I thought, "If I get this working, encapsulating in classes will be easy". The problem is that this code works fine only the first run; afterwards, it cannot resolve the IP address. Which could be the reason?
I am trying to encapsulate Linux sockets and POSIX threads in C++ classes (I work in Knoppix, using KDevelop). Since sockets and threads are new to me, I searched for example code and found the following:
Code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <netdb.h>
#include <signal.h>
#include <fcntl.h>
#include <netinet/ip.h>
#include <pthread.h>
struct sockaddr_in getipa(const char*, int);
void printerror(const char*);
void* runclient(void*);
void* runserver(void*);
int main(){
pthread_t server;
pthread_t client;
if(pthread_create(&server, NULL, runserver, NULL) != 0){
puts("Could not create server thread");
return EXIT_FAILURE;
}
if(pthread_create(&client, NULL, runclient, NULL) != 0){
puts("Could not create client thread");
return EXIT_FAILURE;
}
pthread_join(server, NULL);
pthread_join(client, NULL);
return EXIT_SUCCESS;
}
struct sockaddr_in getipa(const char* hostname, int port){
struct sockaddr_in ipa;
ipa.sin_family = AF_INET;
ipa.sin_port = htons(port);
struct hostent* localhost = gethostbyname(hostname);
if(!localhost){
printerror("resolveing localhost");
return ipa;
}
char* addr = localhost->h_addr_list[0];
memcpy(&ipa.sin_addr.s_addr, addr, sizeof addr);
return ipa;
}
void printerror(const char* action){
int errnum = errno;
errno = 0;
if(errnum > 0){
printf("An error occured while %s.nError code: %inError description: %sn",
action, errnum, strerror(errnum));
}else if(h_errno > 0){
printf("An error occured while %s.nError code: %inError description: %sn",
action, h_errno, hstrerror(h_errno));
h_errno = 0;
}else{
printf("An error occured while %s.n There is no error data.n", action);
}
}
void* runserver(void* context){
struct protoent* tcp;
tcp = getprotobyname("tcp");
int sfd = socket(PF_INET, SOCK_STREAM, tcp->p_proto);
if(sfd == -1){
printerror("createing a tcp socket");
return NULL;
}
struct sockaddr_in isa = getipa("localhost", 1025);
if(bind(sfd, (struct sockaddr*)&isa, sizeof isa) == -1){
printerror("binding socket to IP address");
return NULL;
}
if(listen(sfd, 1) == -1){
printerror("setting socket to listen");
return NULL;
}
int cfd = accept(sfd, NULL, NULL);
if(cfd == -1){
if(errno == EAGAIN || errno == EWOULDBLOCK){
puts("SIGIO recieved for listen socket, but don't know why.");
}else{
printerror("accepting a connection");
return NULL;
}
}
char msg[] = "Message to be sent";
if(send(cfd, (void*) msg, sizeof msg, MSG_NOSIGNAL) == -1){
printerror("sending message to client");
}
shutdown(cfd, SHUT_RDWR);
return NULL;
}
void* runclient(void* context){
struct protoent* tcp;
tcp = getprotobyname("tcp");
int sfd = socket(PF_INET, SOCK_STREAM, tcp->p_proto);
if(sfd == -1){
printerror("createing a tcp socket");
return NULL;
}
struct sockaddr_in isa = getipa("localhost", 1025);
if(connect(sfd, (struct sockaddr*)&isa, sizeof isa) == -1){
printerror("connecting to server");
return NULL;
}
char buff[255];
ssize_t size = recv(sfd, (void*)buff, sizeof buff, MSG_WAITALL);
if(size == -1){
printerror("recieving data from server");
}else{
buff[size] = '';
puts(buff);
}
shutdown(sfd, SHUT_RDWR);
return NULL;
}
Comment