An interesting problem with accept() - TCP-IP

This is a discussion on An interesting problem with accept() - TCP-IP ; Hello, I'd recently been trying something with the unix sockets and I need some help with my accept functions extraordinary behaviour. First of all, my native operating system is Windows XP and I also run a ubuntu server edition on ...

+ Reply to Thread
Results 1 to 12 of 12

Thread: An interesting problem with accept()

  1. An interesting problem with accept()

    Hello, I'd recently been trying something with the unix sockets and I
    need some help with my accept functions extraordinary behaviour.

    First of all, my native operating system is Windows XP and I also run
    a ubuntu server edition on VMWare.

    I've written two programs. One is server and other is client. What the
    server does is simple, it just displays messages received from the
    client, and what the client does is sending messages to server. The
    server runs under ubuntu server (vmware) and the client runs under
    windows.

    Here is the code of the server (the one runs under linux) :

    #include
    #include
    #include
    #include
    #include
    #include
    #include

    #define PORTNO 5050

    int read_socket(int s, void *pBuf, int n);

    int main()
    {
    int serverSocket, clientSocket;
    struct sockaddr_in sinServer, sinClient;
    int client_addrlen;

    if ((serverSocket = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
    perror("Cannot create socket!");
    exit(EXIT_FAILURE);
    }

    sinServer.sin_family = AF_INET;
    sinServer.sin_port = htons(PORTNO);
    sinServer.sin_addr.s_addr = htonl(INADDR_ANY);

    if (bind(serverSocket, (const struct sockaddr *)&sinServer, sizeof
    sinServer) == -1) {
    perror("Cannot bind socket!");
    exit(EXIT_FAILURE);
    }

    if (listen(serverSocket, 8) == -1) {
    perror("Cannot listen!");
    exit(EXIT_FAILURE);
    }

    printf("Waiting for connection!\n");

    if ((clientSocket = accept(serverSocket, (struct sockaddr *)
    &sinClient, &client_addrlen)) == -1) {
    perror("Cannot accept!");
    exit(EXIT_FAILURE);
    }

    printf("Connected!\n");
    printf("Client IP = %s\n", inet_ntoa(sinClient.sin_addr));
    printf("Client port = %d\n", ntohs(sinClient.sin_port));

    {
    char s[32];

    for (; {
    read_socket(clientSocket, s, sizeof s);
    puts(s);
    if (!strcmp(s, "quit"))
    break;
    }
    }

    shutdown(serverSocket, SHUT_RDWR);


    return 0;
    }

    int read_socket(int s, void *pBuf, int n)
    {
    int result;
    int index = 0;
    int left = n;

    while (left > 0) {
    result = recv(s, (char *)pBuf + index, left, 0);
    if (result == 0)
    return index;
    if (result == -1)
    return index;

    index += result;
    left -= result;
    }
    return index;
    }


    And here is the code of client (one that runs under windows) :

    #include
    #include
    #include
    #include

    #define PORTNO 5050

    int write_socket(SOCKET s, const void *pBuf, int n);

    int main()
    {
    WSADATA wsd;
    int result;
    SOCKET serverSocket;
    struct sockaddr_in sinServer;
    char hostname[] = "192.168.71.128"; /*IP address of vmware, when i
    write ifconfig under vmware, this is shown. */
    struct hostent *host;

    if ((result = WSAStartup(MAKEWORD(2, 2), &wsd)) != 0) {
    fprintf(stderr, "Cannot load winsock library: %d\n", result);
    exit(EXIT_FAILURE);
    }

    if ((serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) ==
    INVALID_SOCKET) {
    fprintf(stderr, "Cannot create socket: %d\n", WSAGetLastError());
    exit(EXIT_FAILURE);
    }

    sinServer.sin_family = AF_INET;
    sinServer.sin_port = htons(PORTNO);
    sinServer.sin_addr.s_addr = inet_addr(hostname);
    if (sinServer.sin_addr.s_addr == INADDR_NONE) {
    host = gethostbyname(hostname);
    if (host == NULL) {
    fprintf(stderr, "Cannot resolve hostname: %s\n", hostname);
    exit(EXIT_FAILURE);
    }
    memcpy(&sinServer.sin_addr.s_addr, host->h_addr_list[0], host-
    >h_length);

    }

    if (connect(serverSocket, (const struct sockaddr *)&sinServer, sizeof
    sinServer) == SOCKET_ERROR) {
    fprintf(stderr, "Cannot connect to server!: %d\n",
    WSAGetLastError());
    exit(EXIT_FAILURE);
    }

    {
    char s[32];
    for (; {
    printf("Text: ");
    gets(s);
    write_socket(serverSocket, s, sizeof s);
    if (!strcmp(s, "quit"))
    break;
    }
    }

    WSACleanup();

    return 0;
    }

    int write_socket(SOCKET s, const void *pBuf, int n)
    {
    int result;
    int index = 0;
    int left = n;

    while (left > 0) {
    result = send(s, (const char *)pBuf + index, left, 0);
    if (result == 0)
    return index;
    if (result == SOCKET_ERROR)
    return index;
    index += result;
    left -= result;
    }

    return index;
    }


    interesting point here is that. when i run server under linux and
    after run client under windows, server prints the message "Cannot
    accept!: Invalid Arguement" and stops running. When i comment out the
    block after accept (which is { char s[32] and bla bla..} ) it just
    connects. (prints connected and prints an ip and a port number, then
    quits.)

    How is it possible? Why does it not connect when i don't comment out
    the infinite-loop part?


  2. Re: An interesting problem with accept()

    I suspect this is it:

    hayri ugur koltuk writes:

    [...]

    > if ((serverSocket = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
    > perror("Cannot create socket!");
    > exit(EXIT_FAILURE);
    > }
    >


    [...]

    > if ((clientSocket = accept(serverSocket, (struct sockaddr *)
    > &sinClient, &client_addrlen)) == -1) {
    > perror("Cannot accept!");
    > exit(EXIT_FAILURE);
    > }


    [...]

    > char s[32];
    >
    > for (; {
    > read_socket(clientSocket, s, sizeof s);
    > puts(s);
    > if (!strcmp(s, "quit"))
    > break;
    > }



    [...]

    > shutdown(serverSocket, SHUT_RDWR);


    After the client connects, you're shutting down the server socket
    instead of the client socket.

    Also, I think there are a few problems with your read_socket. First,
    after calling it you are using functions which take a NUL-terminated
    string, like puts and strcmp, but I don't see anything making sure
    there is a NUL at the end. And it looks like your server is reading
    until it gets 32 characters or end-of-file, but the client seems to be
    sending data line-at-a-time. Maybe you are always sending one line
    the EOF, so it works, but it seems somewhat unusual.

    Hope this helps,

    ----Scott.

  3. Re: An interesting problem with accept()

    In article <649a4dd7-4a10-4cb1-92de-dd4e5e01fb6d@m44g2000hsc.googlegroups.com>, ugurkoltuk@gmail.com (hayri ugur koltuk) writes:

    | Hello, I'd recently been trying something with the unix sockets and I
    | need some help with my accept functions extraordinary behaviour.

    You are not initializing client_addrlen.

    Dan Lanciani
    ddl@danlan.*com

  4. Re: An interesting problem with accept()

    On Jun 15, 10:23*pm, ddl@danlan.*com (Dan Lanciani) wrote:
    > In article <649a4dd7-4a10-4cb1-92de-dd4e5e01f...@m44g2000hsc.googlegroups..com>, ugurkol...@gmail.com (hayri ugur koltuk) writes:
    >
    > | Hello, I'd recently been trying something with the unix sockets and I
    > | need some help with my accept functions extraordinary behaviour.
    >
    > You are not initializing client_addrlen.
    >


    Why would not initializing client_addrlen matter when doing call by
    value-result?

    Chad

  5. Re: An interesting problem with accept()

    In article
    <9dab91e5-b2b3-4d48-9c3a-b0fd3b87e9dc@i36g2000prf.googlegroups.com>,
    grocery_stocker wrote:

    > On Jun 15, 10:23*pm, ddl@danlan.*com (Dan Lanciani) wrote:
    > > In article
    > > <649a4dd7-4a10-4cb1-92de-dd4e5e01f...@m44g2000hsc.googlegroups.com>,
    > > ugurkol...@gmail.com (hayri ugur koltuk) writes:
    > >
    > > | Hello, I'd recently been trying something with the unix sockets and I
    > > | need some help with my accept functions extraordinary behaviour.
    > >
    > > You are not initializing client_addrlen.
    > >

    >
    > Why would not initializing client_addrlen matter when doing call by
    > value-result?


    From the man page:

    The address_len is a value-result parameter; it should initially
    contain the amount of space pointed to by address; on return it
    will contain the actual length (in bytes) of the address returned.

    --
    Barry Margolin, barmar@alum.mit.edu
    Arlington, MA
    *** PLEASE don't copy me on replies, I'll read them in the group ***

  6. Re: An interesting problem with accept()

    On Jun 19, 6:36*pm, Barry Margolin wrote:
    > In article
    > <9dab91e5-b2b3-4d48-9c3a-b0fd3b87e...@i36g2000prf.googlegroups.com>,
    >
    > *grocery_stocker wrote:
    > > On Jun 15, 10:23*pm, ddl@danlan.*com (Dan Lanciani) wrote:
    > > > In article
    > > > <649a4dd7-4a10-4cb1-92de-dd4e5e01f...@m44g2000hsc.googlegroups.com>,
    > > > ugurkol...@gmail.com (hayri ugur koltuk) writes:

    >
    > > > | Hello, I'd recently been trying something with the unix sockets and I
    > > > | need some help with my accept functions extraordinary behaviour.

    >
    > > > You are not initializing client_addrlen.

    >
    > > Why would not initializing client_addrlen matter when doing call by
    > > value-result?

    >
    > From the man page:
    >
    > * * *The address_len is a value-result parameter; it should initially
    > * * *contain the amount of space pointed to by address; on return it
    > * * *will contain the actual length (in bytes) of the address returned.
    >
    > --


    Why would not intializing client_addrlen matter? client_addrlen is
    going to get the correct value when the function returns. If there is
    a failure, wouldn't the error get copied over to client_addrlen and
    hence overwrite the unitialized value of client_addrlen?

    Chad

  7. Re: An interesting problem with accept()

    grocery_stocker wrote:
    > On Jun 19, 6:36 pm, Barry Margolin wrote:
    >> In article
    >> <9dab91e5-b2b3-4d48-9c3a-b0fd3b87e...@i36g2000prf.googlegroups.com>,
    >>
    >> grocery_stocker wrote:
    >>> On Jun 15, 10:23 pm, ddl@danlan.*com (Dan Lanciani) wrote:
    >>>> In article
    >>>> <649a4dd7-4a10-4cb1-92de-dd4e5e01f...@m44g2000hsc.googlegroups.com>,
    >>>> ugurkol...@gmail.com (hayri ugur koltuk) writes:
    >>>> | Hello, I'd recently been trying something with the unix sockets and I
    >>>> | need some help with my accept functions extraordinary behaviour.
    >>>> You are not initializing client_addrlen.
    >>> Why would not initializing client_addrlen matter when doing call by
    >>> value-result?

    >> From the man page:
    >>
    >> The address_len is a value-result parameter; it should initially
    >> contain the amount of space pointed to by address; on return it
    >> will contain the actual length (in bytes) of the address returned.

    >
    > Why would not intializing client_addrlen matter?


    A value-result parameter means the value pointed to is used, as well as
    (possibly) being updated by the function. In this particular case,
    accept() will check the value pointed to is no smaller than the size of
    the address, and fail if it isn't.

    Alex

  8. Re: An interesting problem with accept()

    On Fri, 20 Jun 2008 12:51:34 -0700, grocery_stocker wrote:

    > Why would not intializing client_addrlen matter? client_addrlen is going
    > to get the correct value when the function returns. If there is a
    > failure, wouldn't the error get copied over to client_addrlen and hence
    > overwrite the unitialized value of client_addrlen?


    Because the function wants to know if you allocated enough memory for the
    value it wants to store. Otherwise it has to assume this and if you
    didn't allocate enough memory, something will get corrupted.

    M4

  9. Re: An interesting problem with accept()

    On Jun 20, 1:36*pm, Martijn Lievaart wrote:
    > On Fri, 20 Jun 2008 12:51:34 -0700, grocery_stocker wrote:
    > > Why would not intializing client_addrlen matter? client_addrlen is going
    > > to get the correct value when the function returns. If there is a
    > > failure, wouldn't the error get copied over to client_addrlen and hence
    > > overwrite the unitialized value of client_addrlen?

    >
    > Because the function wants to know if you allocated enough memory for the
    > value it wants to store. Otherwise it has to assume this and if you
    > didn't allocate enough memory, something will get corrupted.
    >


    I didn't know it was possible to allocate memory using something like
    sizeof().

  10. Re: An interesting problem with accept()

    grocery_stocker wrote:

    > On Jun 20, 1:36*pm, Martijn Lievaart wrote:
    >> On Fri, 20 Jun 2008 12:51:34 -0700, grocery_stocker wrote:
    >> > Why would not intializing client_addrlen matter? client_addrlen is
    >> > going to get the correct value when the function returns. If there
    >> > is a failure, wouldn't the error get copied over to client_addrlen
    >> > and hence overwrite the unitialized value of client_addrlen?

    >>
    >> Because the function wants to know if you allocated enough memory for
    >> the value it wants to store. Otherwise it has to assume this and if
    >> you didn't allocate enough memory, something will get corrupted.
    >>

    >
    > I didn't know it was possible to allocate memory using something like
    > sizeof().


    Sizeof is evaluated at compile time, so you can use it in allocating
    dynamic memory (with malloc and friends) but you can't use it for
    static allocations (though with C99 you can use it with Variable Length
    Arrays.)


  11. Re: An interesting problem with accept()

    santosh wrote:

    > Sizeof is evaluated at compile time, so you can use it in allocating
    > dynamic memory (with malloc and friends) but you can't use it for
    > static allocations (though with C99 you can use it with Variable Length
    > Arrays.)


    /* BEGIN new.c */

    #include

    int main (void)
    {
    static char array[sizeof (char)];

    if (sizeof array == 1) {
    puts("What do you mean by "
    "\"can't use it for static allocations\"?");
    }
    return 0;
    }

    /* END new.c */

    --
    pete

  12. Re: An interesting problem with accept()

    santosh writes:

    > grocery_stocker wrote:
    >
    >> On Jun 20, 1:36*pm, Martijn Lievaart wrote:
    >>> On Fri, 20 Jun 2008 12:51:34 -0700, grocery_stocker wrote:
    >>> > Why would not intializing client_addrlen matter? client_addrlen is
    >>> > going to get the correct value when the function returns. If there
    >>> > is a failure, wouldn't the error get copied over to client_addrlen
    >>> > and hence overwrite the unitialized value of client_addrlen?
    >>>
    >>> Because the function wants to know if you allocated enough memory for
    >>> the value it wants to store. Otherwise it has to assume this and if
    >>> you didn't allocate enough memory, something will get corrupted.
    >>>

    >>
    >> I didn't know it was possible to allocate memory using something like
    >> sizeof().

    >
    > Sizeof is evaluated at compile time, so you can use it in allocating
    > dynamic memory (with malloc and friends) but you can't use it for
    > static allocations (though with C99 you can use it with Variable Length
    > Arrays.)


    I am not sure what you mean by "static allocation", but sizeof can be
    used as part of an array size (with some restriction) in almost all
    cases. You can certainly use it for automatic arrays, file-scope
    arrays and arrays with the static storage class specifier.

    To get a VLA from it you'd need to take the size of another VLA object
    or include in the expression some term that is not a compile-time
    constant.

    --
    Ben.

+ Reply to Thread