tags:

views:

247

answers:

2

Hello,

Linux GCC 4.4.2

I am doing some socket programming.

However, I keep getting this error when I try and assign the sockfd from the socket function.

" Socket operation on non-socket"

Many thanks for any advice,

#if defined(linux)
#include <pthread.h>
/* Socket specific functions and constants */
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <errno.h>
#endif

#include "server.h"
#include "cltsvr_ults.h"

/* Listens for a connection on the designated port */
void wait_client()
{
    struct addrinfo add_info, *add_res;
    int sockfd;

    /* Load up the address information using getaddrinfo to fill the struct addrinfo */
    memset(&add_info, 0, sizeof(add_info));
    /* Use either IPv4 or IPv6 */
    add_info.ai_family = AF_UNSPEC; 
    add_info.ai_socktype = SOCK_STREAM;
    /* Fill in my IP address */
    add_info.ai_flags = AI_PASSIVE;

    /* Fill the struct addrinfo */
    int32_t status = 0;
    if(status = getaddrinfo(NULL, "6000", &add_info, &add_res) != 0)
    {
        fprintf(stderr, "getaddrinfo [ %s ]\n", gai_strerror(status));

        return;
    }

    if((sockfd = (socket(add_res->ai_family, add_res->ai_socktype, add_res->ai_protocol)) == -1))
    {
        fprintf(stderr, "Socket failed [ %s ]\n", strerror(errno));

        return;
    }

    /* Bind to the port that has been assigned by getaddrinfo() */
    if(bind(sockfd, add_res->ai_addr, add_res->ai_addrlen) != 0)
    {
        fprintf(stderr, "Bind failed [ %s ]\n", strerror(errno));

        return;
    }

    printf("Listening for clients\n");
}

Edit == coding in the old-school method

    int32_t sockfd = 0;
    struct sockaddr_in my_addr;

    memset(&my_addr, 0, sizeof(my_addr));

    my_addr.sin_family = AF_INET;
    my_addr.sin_port = htons(6000);
    my_addr.sin_addr.s_addr = inet_addr("127.0.0.1");

    sockfd = socket(PF_INET, SOCK_STREAM, 0);
    if(sockfd == -1)
    {
    fprintf(stderr, "Socket failed [ %s ]\n", strerror(errno));
    return;
    }

    if(bind(sockfd, (struct sockaddr *) &my_addr, sizeof(my_addr)) == -1)
    {
    fprintf(stderr, "Bind failed [ %s ]\n", strerror(errno));
    return;
    }
+8  A: 

Your main problem is that you have the wrong check for when socket() has an error. socket() will return -1 on error, not 0 on success. You may be getting a good socket value (2, 3, etc.) and treating it like an error.

There is also a second problem in the way you are parenthesizing your code. When you write:

if (sockfd = socket(add_res->ai_family, add_res->ai_socktype, add_res->ai_protocol) != 0)

That is being treated as:

if (sockfd = (socket(add_res->ai_family, add_res->ai_socktype, add_res->ai_protocol) != 0))

So sockfd will not be assigned the return value of socket, but the value of comparing it against 0. Fixing both problems, you should be writing:

if ((sockfd = socket(add_res->ai_family, add_res->ai_socktype, add_res->ai_protocol)) == -1)
R Samuel Klatchko
Thanks. That was correct. However, I am now getting an error " Socket operation on non-socket". I have edited my code with your correct line. Any reason why I am getting this error? Many thanks
robUK
@roboUK - are you sure you are getting that error from the code you posted as "Edit". When I compile that snippet and run it, it runs fine.
R Samuel Klatchko
A: 

I believe you should be specifying the type of socket you want. When you say:

add_info.ai_family = AF_UNSPEC;

you should be saying:

add_info.ai_family = AF_INET;
anon
I changed that line of code to AF_INET, but still getting the same error.
robUK
I'm not convinced that your call to getaddrinfo() is correct either. why don't you simply follow one of the many "old school" examples of how to use a socket.
anon
Hello, I have edited my source code to include the old-school method. That worked ok. However, I am still interested to know why using getaddrinfo() failed? Many thanks,
robUK