mstrelan
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);
}
exact error message pls.
Can you tell what the exact error message is ? As well as when you get it ?
ASKER
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
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 ?
Can we assume that you didn't get that error when you didn't link to the pthread library ?
ASKER
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.
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;
}
ASKER
sorry what i meant to say is "remove everything after 308"
when adding line 309 i get the error
when adding line 309 i get the error
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
With -pthread I still get the error :(
ASKER
and when i said everything after 308 i meant everything after 307 :P
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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.
ASKER
> 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"
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"
ASKER