[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 701
  • Last Modified:

Server demo program returns "accept: Bad address"

Hi

I built one server demo program on SunOS and got the run time error as I ran it.
server: accept: Bad address

The ADDRESS is set to the machine's IP address. I don't know why I got that error, indicating server can't accept a connection on its won IP. server is the name of this demo program.
Thanks

-chuehw


Here is the source code.
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <stdio.h>

#define NSTRS       3           /* no. of strings  */
#define ADDRESS     "146.x.y.z"  /* addr to connect */

/*
 * Strings we send to the client.
 */
char *strs[NSTRS] = {
    "This is the first string from the server.\n",
    "This is the second string from the server.\n",
    "This is the third string from the server.\n"
};

main()
{
    char c;
    FILE *fp;
    int fromlen;
    register int i, s, ns, len;
    struct sockaddr_un saun, fsaun;

    /*
     * Get a socket to work with.  This socket will
     * be in the UNIX domain, and will be a
     * stream socket.
     */
    if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
        perror("server: socket");
        exit(1);
    }

    /*
     * Create the address we will be binding to.
     */
    saun.sun_family = AF_UNIX;
    strcpy(saun.sun_path, ADDRESS);

    /*
     * Try to bind the address to the socket.  We
     * unlink the name first so that the bind won't
     * fail.
     *
     * The third argument indicates the "length" of
     * the structure, not just the length of the
     * socket name.
     */
    unlink(ADDRESS);
    len = sizeof(saun.sun_family) + strlen(saun.sun_path);

    if (bind(s, &saun, len) < 0) {
        perror("server: bind");
        exit(1);
    }

    /*
     * Listen on the socket.
     */
    if (listen(s, 5) < 0) {
        perror("server: listen");
        exit(1);
    }

    /*
     * Accept connections.  When we accept one, ns
     * will be connected to the client.  fsaun will
     * contain the address of the client.
     */
    if ((ns = accept(s, &fsaun, &fromlen)) < 0) {
        perror("server: accept");
        exit(1);
    }

    /*
     * We'll use stdio for reading the socket.
     */
    fp = fdopen(ns, "r");

    /*
     * First we send some strings to the client.
     */
    for (i = 0; i < NSTRS; i++)
        send(ns, strs[i], strlen(strs[i]), 0);

    /*
     * Then we read some strings from the client and
     * print them out.
     */
    for (i = 0; i < NSTRS; i++) {
        while ((c = fgetc(fp)) != EOF) {
            putchar(c);

            if (c == '\n')
                break;
        }
    }

    /*
     * We can simply use close() to terminate the
     * connection, since we're done with both sides.
     */
    close(s);

    exit(0);
}

0
chuehw
Asked:
chuehw
  • 2
  • 2
1 Solution
 
stefan73Commented:
Hi chuehw,
Looks like you have a problem in the call sequence of your app.

Check this tutorial:
http://www.ecst.csuchico.edu/~beej/guide/net/



Cheers,
Stefan
0
 
chuehwAuthor Commented:
stefan73,
I found the root cause. But I don't know why.
I need to set the var fromlen to global variable in order to let accept being able to accept a connection. When fromlen was declared as local var to main( ), accept() returns "Bad address". This is verified. But I have no clue why it behaves like that.

-chuehw

 if ((ns = accept(s, &fsaun, &fromlen)) < 0) {
        perror("server: accept");
        exit(1);
    }
0
 
chuehwAuthor Commented:
OK. I think I need to initialize fromlen to 0. So when I declare fromlen global, it was set to 0 by default ?

I did another test. I declare fromlen local to main( ) but this time I initialize it to 0 and accept( ) works this time.
Two sets of solutions:
1. declare fromlen to global. Don't care to initialize it to 0 or not.
2. declare fromlen to local but need to initialize it to 0.

-chuehw
0
 
Karl Heinz KremerCommented:
The "addrlen" parameter (what you call fromlen) needs to be set to the size of the struct the second parameter points to (in your case sockaddr_un). So before you call accept(), you should do the following:

    fromlen = sizeof(sockaddr_un);

You can find this information in the man page (man 2 access), but also in the tutorial that stefan73 provided a link to.
0
 
Karl Heinz KremerCommented:
BTW: I don't know why it works with fromlen set to 0, but this is not the way this function is supposed to be used.
0

Featured Post

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

  • 2
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now