multiple times connect()

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

multiple times connect()

Steffen Wendzel-2
hi,

I just wondering why connect() returns different error values
after multiple calls. my code snipped is as follows:

----------------snip-------------------
while (1) {
        if (connect(sockfd, (struct sockaddr *) &sa,
                    sizeof(struct sockaddr_in)) == -1)
                perror("connect");
        else
                printf("connected.\n");
}
----------------snap-------------------

If I start the programm and connect() is unable to connect, I
get the following output:

connect: Connection refused
connect: Invalid argument
.
.
connect: Invalid argument

I found a hint in the Usenet to close the sockfd and reopen it.
After I implemented the close(sockfd) and sockfd=socket(...)
it worked:

----------------snip-------------------
while (1) {
        if (connect(sockfd, (struct sockaddr *) &sa,
                    sizeof(struct sockaddr_in)) == -1) {
                perror("connect");
                close(sockfd);
                if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
                        err(1, "socket()");
        } else
                printf("connected.\n");
}
----------------snap-------------------

connect: Connection refused
connect: Connection refused
connect: Connection refused
.
.
.

This is, what I wanted. But why do I have to re-open the socket? does
connect() internaly close the descriptor?

I first searched the kernel code to understand this and found a comment
in uipc_socket.c's soconnect():

        /*
         * If protocol is connection-based, can only connect once.
         * Otherwise, if connected, try to disconnect first.
         * This allows user to disconnect by connecting to, e.g.,
         * a null address.
         */

But I'm not sure if my socket file descriptor is marked as 'connected'
if my program receives a 'Connection refused' error. And why should it
be helpful to disconnect by connecting to a null address?

Steffen

--
http://cdp.doomed-reality.org

Reply | Threaded
Open this post in threaded view
|

Re: multiple times connect()

Theo de Raadt
> I just wondering why connect() returns different error values
> after multiple calls. my code snipped is as follows:
>
> ----------------snip-------------------
> while (1) {
> if (connect(sockfd, (struct sockaddr *) &sa,
>                     sizeof(struct sockaddr_in)) == -1)
> perror("connect");
> else
> printf("connected.\n");
> }
> ----------------snap-------------------
>
> If I start the programm and connect() is unable to connect, I
> get the following output:
>
> connect: Connection refused
> connect: Invalid argument
> .
> .
> connect: Invalid argument


Because a stream socket may be used only once.  A call to connect
is considered use.

> I found a hint in the Usenet to close the sockfd and reopen it.

That is not just a hint.  You MUST do so.

> After I implemented the close(sockfd) and sockfd=socket(...)
> it worked:
>
> ----------------snip-------------------
> while (1) {
> if (connect(sockfd, (struct sockaddr *) &sa,
>                     sizeof(struct sockaddr_in)) == -1) {
> perror("connect");
> close(sockfd);
> if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
> err(1, "socket()");
> } else
> printf("connected.\n");
> }
> ----------------snap-------------------
>
> connect: Connection refused
> connect: Connection refused
> connect: Connection refused
> .
> .
> .
>
> This is, what I wanted. But why do I have to re-open the socket? does
> connect() internaly close the descriptor?

No, the descriptor is still open, but it has been used.  It cannot be
used again.

> I first searched the kernel code to understand this and found a comment
> in uipc_socket.c's soconnect():
>
> /*
> * If protocol is connection-based, can only connect once.
> * Otherwise, if connected, try to disconnect first.
> * This allows user to disconnect by connecting to, e.g.,
> * a null address.
> */
>
> But I'm not sure if my socket file descriptor is marked as 'connected'
> if my program receives a 'Connection refused' error. And why should it
> be helpful to disconnect by connecting to a null address?

The problem you face is that Linux does it wrong.  So quite a few
people write their code wrong.  But historically, you have never been
able to reuse a SOCK_STREAM socket.

Reply | Threaded
Open this post in threaded view
|

Re: multiple times connect()

Ted Unangst-2
In reply to this post by Steffen Wendzel-2
On 8/31/06, Steffen Wendzel <[hidden email]> wrote:
> This is, what I wanted. But why do I have to re-open the socket? does
> connect() internaly close the descriptor?

the socket is "damaged" by connect.  why?  "because."

> I first searched the kernel code to understand this and found a comment
> in uipc_socket.c's soconnect():

it would have been faster to read the man page: "stream sockets may
use connect() only once;"