Link to home
Start Free TrialLog in
Avatar of mstrelan
mstrelanFlag for Australia

asked on

when compiling with -lpthread i get ai_socktype not supported

any ideas why? code that throws this error is below
// get us a socket and bind it
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags = AI_PASSIVE;
    if ((rv = getaddrinfo(NULL, PORT, &hints, &ai)) != 0) {
        fprintf(stderr, "selectserver: %s\n", gai_strerror(rv));
        exit(1);
    }

Open in new window

Avatar of mstrelan
mstrelan
Flag of Australia image

ASKER

more information - it ran the first time but said #1 SMP Mon Aug 25 17:32:09 UTC 2008 and now it wont run when i compile with threads
Avatar of sunnycoder
exact error message pls.
Can you tell what the exact error message is ? As well as when you get it ?
exact error:

selectserver: ai_socktype not supported

its weird because the every LOC in the main method above this is identical to Beej's selectserver example. can't find anything on google
What socket library (and version) are you using ?
And on what platform ?

Can we assume that you didn't get that error when you didn't link to the pthread library ?
I'm on Ubuntu 8.04. I have no reference to pthread.h in my c file. Runs ok when i dont compile with -lpthread but when I do I get the error. I'm going to post my source file (i know its disgusting and pretty bad but i'm learning).

I debugged by removing parts of main(). If i remove everything AFTER line 309 its fine. As soon as I add in the declaration of def it decides to break.
/**
 * Server.c 
 *  Provides a dictionary look up service that a Client can connect to.
 *
 *  Largely based on the following example
 *  http://beej.us/guide/bgnet/output/html/singlepage/bgnet.html#select
 *
 */
 
 
/* --------------------------------------------------------------------------
 * Included Files
 * -------------------------------------------------------------------------- */ 
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <errno.h>
 
#include <ctype.h>
 
/* --------------------------------------------------------------------------
 * Definitions for use on the Server
 * -------------------------------------------------------------------------- */
 
#define PORT "9036"   // port we're listening on
#define DICTIONARY_FILE "dictionary.txt" // location of the dictionary text file
#define MAX_LINE_LENGTH 1024 // maximum characters in a definition
#define MAX_WORD_COUNT 100 // maximum words in a dictionary
#define ERROR_MESSAGE_NOTFOUND 0; // id of the not found error message
 
 
/* --------------------------------------------------------------------------
 * Global variables
 * -------------------------------------------------------------------------- */
 
char** words;	// the buffer of words in the dictionary
char** definitions; // the buffer of definitions. indexes match words buffer.
char** errorMessages; // why not keep all the available errors in an array?
int wordCount = 0; // the size of the dictionary
 
void *workthread(void *arg);
 
/* --------------------------------------------------------------------------
 * Methods / Functions
 * -------------------------------------------------------------------------- */
 
/**
 * Traverses the words array trying to find the search term
 * @return	int		The index of the definition or -1 if not found
 */
int getDefinition(char* word) {
 	int i = 0;
	for (i = 0; i < wordCount; i++) {
		if (strcmp(words[i], word) == 0) {
			return i;
			break;
		}
	}
	return -1;
} // end function getDefinition.
 
 
/**
 * Parses the dictionary into the two buffers.
 * @param	filename	The relative location of the text file.
 */
int readFile(char* filename) {
 
	FILE *fp; // this will point to the file we need to read
	
	char ch; // current character we're reading
	char* tempString; // buffer for the current string
 
	int i = 0; // index of the character in the current string
	int j = 0; // index of the words in the array
 
	printf("........... Loading the Database from disk\n");
	
	// open the file or throw an error if it can't
	if((fp = fopen(filename, "r")) == NULL) {
		printf("Cannot open file.\n");
		exit(1);
	}
	
	// allocate some memory to store the current string
	tempString = (char*)malloc(MAX_LINE_LENGTH);
 
	// and allocate some memory for the arrays
	words = (char**) malloc(MAX_LINE_LENGTH * MAX_WORD_COUNT);
	definitions = (char**) malloc(MAX_LINE_LENGTH * MAX_WORD_COUNT);
 
	// get one char at a time until the end of the file
	while((ch = fgetc(fp))!= EOF) {
 
		// if its an @ symbol then we're at the end of a string
		if (ch == '@') {
			if (strlen(tempString) > 0) {
				tempString[i++] = '\0';
 
				// if its the first string on a line we add it to the words array
				if (j % 2 == 0) {
					words[j/2] = (char*)malloc(MAX_LINE_LENGTH);
					strcpy(words[j/2], tempString);
					wordCount++;
					
				// but if its the second string on a line we add to definitions
				} else {
					definitions[j/2] = (char*)malloc(MAX_LINE_LENGTH);
					strcpy(definitions[j/2], tempString);
				}
 
				j++;
 
			}
 
			// clear out the temp string and reset the iterator
			bzero(tempString, strlen(tempString));	
			i = 0;
 
		// if its a new line then we ignore it and wait for the @
		} else if (ch == '\n') {
			; 
		// but if its a plain old character then we just add it to the current string
		} else {
			if (i < MAX_LINE_LENGTH) {
				tempString[i++] = ch;
			}
		}
		
	} // EOF reached.
 
	// the last string hasn't been processed so lets do that now
	tempString[i++] = '\0';
	if (j % 2 == 0) {
		words[j/2] = (char*)malloc(strlen(tempString));
		strcpy(words[j/2], tempString);
	} else {
		definitions[j/2] = (char*)malloc(strlen(tempString));
		strcpy(definitions[j/2], tempString);
	}
	j++;
 
	// and then we'll close the file
	fclose(fp);
 
    return 0;
} // end function readFile.
 
 
/**
 * Get sockaddr, IPv4 or IPv6
 */
void *get_in_addr(struct sockaddr *sa) {
    if (sa->sa_family == AF_INET) {
        return &(((struct sockaddr_in*)sa)->sin_addr);
    }
    return &(((struct sockaddr_in6*)sa)->sin6_addr);
}
 
 
/**
 * A helper function to continuously send until all bytes are received on the
 * other end.
 * @param s		The socket identifier
 * @param buf	The string to send on the socket
 * @param len	The length of the string to send
 * @return int	-1 on failure, 0 on success
 */
int sendall(int s, char *buf, int *len) {
 
    int total = 0;        // how many bytes we've sent
    int bytesleft = *len; // how many we have left to send
    int n;	// how many bytes were sent just then
 
    // while there is more to send, keep sending it!
    while(total < *len) {
        n = send(s, buf+total, bytesleft, 0);
        if (n == -1) { break; }
        total += n;
        bytesleft -= n;
    }
 
	// the number of bytes actually sent can be passed back through this pointer
    *len = total;
 
	// return -1 on failure, 0 on success
    return n==-1?-1:0;
    
} // end function sendall.
 
 
/**
 * Initialises my error messages because I had bad problems with segmentation faults
 */
void init() {
	errorMessages = (char**)malloc(255 * 10);
	errorMessages[0] = (char*) malloc(255);
	char* tempString = "Sorry,can't find the description. Please try other terms.";
	int a;
	for (a = 0; a < strlen(tempString); a++) {
		errorMessages[0][a] = tempString[a];
	}
	errorMessages[0][a+1] = '\0';
} // end function init.
 
 
/**
 * 
 */
void *workthread(void *param) {
 
	
	printf("now inside work thread!\n");
 
}
 
 
 
 
/**
 * The main thread of execution.
 */
int main(int argc, char *argv) {
 
	init();
 
 
    fd_set master;    // master file descriptor list
    fd_set read_fds;  // temp file descriptor list for select()
    int fdmax;        // maximum file descriptor number
 
    int listener;     // listening socket descriptor
    int newfd;        // newly accept()ed socket descriptor
    struct sockaddr_storage remoteaddr; // client address
    socklen_t addrlen;
 
    char buf[256];    // buffer for client data
    int nbytes;
 
    char remoteIP[INET6_ADDRSTRLEN];
 
    int yes=1;        // for setsockopt() SO_REUSEADDR, below
    int i, j, rv;
 
    struct addrinfo hints, *ai, *p;
 
    FD_ZERO(&master);    // clear the master and temp sets
    FD_ZERO(&read_fds);
 
    // get us a socket and bind it
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags = AI_PASSIVE;
    if ((rv = getaddrinfo(NULL, PORT, &hints, &ai)) != 0) {
        fprintf(stderr, "selectserver: %s\n", gai_strerror(rv));
        exit(1);
    }
    
    for(p = ai; p != NULL; p = p->ai_next) {
        listener = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
        if (listener < 0) { 
            continue;
        }
        
        // lose the pesky "address already in use" error message
        setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));
 
        if (bind(listener, p->ai_addr, p->ai_addrlen) < 0) {
            close(listener);
            continue;
        }
 
        break;
    }
 
    // if we got here, it means we didn't get bound
    if (p == NULL) {
        fprintf(stderr, "selectserver: failed to bind\n");
        exit(2);
    }
 
    freeaddrinfo(ai); // all done with this
 
    // listen
    if (listen(listener, 10) == -1) {
        perror("listen");
        exit(3);
    }
 
 
 
	readFile(DICTIONARY_FILE);    
    printf("Server Socket created and waiting for clients .......\n");
 
    // add the listener to the master set
    FD_SET(listener, &master);
 
    // keep track of the biggest file descriptor
    fdmax = listener; // so far, it's this one
 
	char* def;
	int def_index;
 
 
 
    return 0;
}

Open in new window

sorry what i meant to say is "remove everything after 308"
when adding line 309 i get the error
SOLUTION
Avatar of Infinity08
Infinity08
Flag of Belgium image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
With -pthread I still get the error :(
and when i said everything after 308 i meant everything after 307 :P
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
No problem. Instead of deleting the question, you can accept your own answer, so the solution is saved in the PAQ database - for your own benefit and that of others that might have the same problem at some later time.
> No problem. Instead of deleting the question, you can accept your own answer, so the solution is saved in the PAQ database

Yes this is what I did - requested for my answer to be accepted. Its pending admin approval

"Notice: mstrelan has requested that this question be closed by accepting mstrelan's comment #22776141 (0 points) as the solution and Infinity08's comment #22775548 (200 points) as the assisted solution for the following reason:
Solved it myself"