connect: Transport endpoint is already connected
Cody Harris

Here's the code:

if (!isconnected){
        printf("Connecting to %s\n",inet_ntoa(outlink_addr.sin_addr));
              if (connect(outsock, (struct sockaddr *)&outlink_addr,sizeof(struct sockaddr)) == -1) {
          perror("connect");
          //close(outsock);  
          //exit(1);
        }else{
          printf("Connected to %s (%d)\n",inet_ntoa(outlink_addr.sin_addr),outsock);
          FD_SET(outsock, &master); // add to master set
          if (outsock > fdmax) {    // keep track of the maximum
            outsock = newfd;
          }
          isconnected = 1;
        }
      }

And the output:

Quote:

Unreal2Hybrid: new connection from 192.168.0.2 on socket 4
Connecting to 63.110.124.45
connect: Transport endpoint is already connected

I can't figure out why it can't reconnect (it connects once, and only once, do I need to reset the struct or something?).

And yes, this is using select, a modified select thingy from Beej. If you want I can post the entire code...

Thomas Fjellstrom

Theres a nice option called something like: SO_REUSEADDR.

ReyBrujo

Most probably the problem is in the bind, not the connect.

It is an operative system issue. If you don't close the socket correctly (in example, press CTRL-C to end the program), the port is never freed. In Linux there used to be a delay of around 30 seconds-1 minute until the OS freed the socket and you were able to bind it again.

Cody Harris

Adding

        if (setsockopt(outsock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {
            perror("setsockopt");
            exit(1);
        }

didn't work, it still complains... Do I have to reset the struct or something...

Thomas Fjellstrom

Heres a little function I found and modified:

1int make_socket (unsigned short port)
2{
3 int sock, yes = 1;
4 struct sockaddr_in name;
5 
6 /* Create the socket. */
7 sock = socket (PF_INET, SOCK_STREAM, 0);
8 if (sock < 0) {
9 /*char *buf = calloc(1, 256);
10 if(!buf)
11 exit (EXIT_FAILURE);
12 */
13 log_printf(global_log, LOG_LEVEL_FATAL, "socket: failed..."/*, strerror_r(errno, buf, 256)*/);
14 //free(buf);
15 exit (EXIT_FAILURE);
16 }
17 if (setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(const char *)&yes,sizeof(int)) == -1) {
18 /*char *buf = calloc(1, 256);
19 if(!buf)
20 exit (EXIT_FAILURE);
21 */
22 log_printf(global_log, LOG_LEVEL_FATAL, "setsockopt: failed..."/*, strerror_r(errno, buf, 256)*/);
23 //free(buf);
24 exit (EXIT_FAILURE);
25 }
26 
27 /* Give the socket a name. */
28 name.sin_family = AF_INET;
29 name.sin_port = htons (port);
30 name.sin_addr.s_addr = htonl (INADDR_ANY);
31 if (bind (sock, (struct sockaddr *) &name, sizeof (name)) < 0) {
32 char *buf = calloc(1, 256);
33 if(!buf)
34 exit (EXIT_FAILURE);
35 
36 log_printf(global_log, LOG_LEVEL_FATAL, "bind: failed..."/*, strerror_r(errno, buf, 256)*/);
37 //free(buf);
38 exit (EXIT_FAILURE);
39 }
40 
41 log_printf(global_log, LOG_LEVEL_NOTE, "Succsessfully bound to port: %i", port);
42 
43 return sock;
44}

The log_* functions are mine, not libc or anything... Oh, and note, this is for a server style port IIRC.

ReyBrujo

How is the server code? It is listening for more connections?

Cody Harris

The server listens for connections, and if it find that when a client connects that it's not connected to another server, then it connects to it...

I want it to reconnect to that socket if the connection is lost.

EDIT: Why do you have to bind when connecting to something else?

ReyBrujo

The code is old, you don't want to open a new port everytime you connect to something ;)

You should show the server code, though. The client should not have problem no matter how many they are.

Cody Harris

I edited it so that it recalled the socket thingy...

1 if (!isconnected){
2 printf("Connecting to %s (cached)\n",inet_ntoa(outlink_addr.sin_addr));
3 if (connect(outsock, (struct sockaddr *)&outlink_addr,sizeof(struct sockaddr)) == -1) {
4 perror("connect");
5 if ((outlink=gethostbyname("palace.morphforest.com")) == NULL){
6 perror("gethostbyname");
7 exit(1);
8 }
9 if ((outsock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
10 perror("socket");
11 exit(1);
12 }
13 outlink_addr.sin_family = AF_INET; // host byte order
14 outlink_addr.sin_port = htons(7029); // short, network byte order
15 outlink_addr.sin_addr = *((struct in_addr *)outlink->h_addr);
16 memset(&(outlink_addr.sin_zero), '\0', 8); // zero the rest of the
17 
18 // lose the pesky "address already in use" error message
19 if (setsockopt(outsock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {
20 perror("setsockopt");
21 exit(1);
22 }
23 printf("Connecting to %s (last attempt)\n",inet_ntoa(outlink_addr.sin_addr));
24 if (connect(outsock, (struct sockaddr *)&outlink_addr,sizeof(struct sockaddr)) == -1) {
25 perror("connect");
26 exit(1);
27 }else{
28 printf("Connected to %s (%d)\n",inet_ntoa(outlink_addr.sin_addr),outsock);
29 FD_SET(outsock, &master); // add to master set
30 if (outsock > fdmax) { // keep track of the maximum
31 outsock = newfd;
32 }
33 isconnected = 1;
34 }
35 //close(outsock);
36 //exit(1);
37 }else{
38 printf("Connected to %s (%d)\n",inet_ntoa(outlink_addr.sin_addr),outsock);
39 FD_SET(outsock, &master); // add to master set
40 if (outsock > fdmax) { // keep track of the maximum
41 outsock = newfd;
42 }
43 isconnected = 1;
44 }
45 }

ReyBrujo

Hmm... close the old socket before creating a new one. And you meant reusing a socket to connect? Ah... I misunderstood, sorry.

Cody Harris

The old one is automatically closed on error or disconnect.

This seems to work though.

ReyBrujo

Hmm... really? It frees the descriptor? Geez... it must have changed since the last time I did some real network programming then...

Cody Harris

Yeah, it reuses file descriptors, the lowest one free (hense if you close stout and open a new file, all stout will go to the file...

That's the logic between piping stout, you close it then you ddup it or whatever...

Thread #412271. Printed from Allegro.cc