Restore connection to the server after its failure

I have a client connected to the server (TCP connection). In the event of a server failure (I disabled it), my client must be connected to another server in order to continue servicing. But when the first server returns, I need to connect the client to it again. I was able to connect my client to the backup server after the first server failure, but I had a problem with reconnecting my client to the first server. I made the create_newconnect() function to reconnect to the server, but it doesn’t work (so I don’t call it in the code) I tried to simplify my program as much as I could, so it wouldn’t be big This is the client side

 #include <stdlib.h> #include <stdio.h> #include <ctype.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <signal.h> #include <string.h> #include <arpa/inet.h> #include <time.h> #define SIZE sizeof(struct sockaddr_in) struct sockaddr_in server; void tcp_protocol();//execute client tcp protocol void server_check(); void tcp(); void create_newconnect(); int main (int argc, char *argv[]) { int portno; //Test for correct number of arguments if (argc != 3) { fprintf(stderr, "Usage: %s Port# IP Address \n", argv[0]); exit(1); } portno = atoi(argv[1]);//convert port # to int server.sin_family = AF_INET; server.sin_port = htons(portno); server.sin_addr.s_addr = inet_addr(argv[2]);//use client ip address tcp();//call tcp function return 0; } void tcp() { int sockfd; char c ; //create socket if ((sockfd = socket(AF_INET, SOCK_STREAM, 0))==-1) { perror ("socket call faild"); exit (1); } //connect to the server if (connect (sockfd, (struct sockaddr *)&server, SIZE)==-1) { perror ("connect call faild"); exit (1); } while(1) { printf("Enter char\n"); scanf("%c",&c); server_check(sockfd); //send packet to server if (send(sockfd, &c, sizeof(c),0)<0) { printf("error sending\n"); } //if packet is received from server if(recv(sockfd, &c, sizeof(c),0)>0) { printf("server respond %c\n", c);//print result } } close(sockfd); } void server_check(int sock) { char b ='b'; //send packet to server if (send(sock, &b, sizeof(b),0)<0) printf("error sending\n"); //if packet is received from server if((recv(sock, &b, sizeof(b),0)>0)) { printf("server responded\n"); } else//if server is not responding { printf("server crashed\n"); close(sock);//close socket server.sin_port = htons(5002); server.sin_addr.s_addr = inet_addr("127.0.0.1"); tcp();//create new connection } } void create_newconnect() { int newsockfd; server.sin_port = htons(5001); //create socket if ((newsockfd = socket(AF_INET, SOCK_STREAM, 0))==-1) { perror ("socket call faild"); exit (1); } //connect to the server if (connect (newsockfd, (struct sockaddr *)&server, SIZE)==-1) { perror ("connect call faild"); exit (1); } tcp();//call function to execute tcp protocol } 
+6
source share
2 answers

I think the first thing you will need to consider: after your first server crashes and your client successfully connects to the backup server, how will your client ever know that the first server has returned the line?

I can imagine two possibilities: perhaps the backup server can notify the client about the reappearance of the primary server (for example, sending some message PRIMARY_SERVER_ONLINE over a TCP connection or maybe just closing TCP, with the expectation that this will force the client to try to connect again to the primary server).

Another approach would be to make your client smart enough so that it periodically (for example, once a minute) tries to reconnect to the main server, even when it uses a TCP connection to the backup server. This is doable, but not with one thread and an I / O lock, like your published code ... (because if your program is blocked in the recv () call, it has no way to do anything else, for example, try to connect TCP -compound). For proper operation, you need to use non-blocking I / O and select () (or similar) or asynchronous I / O or multiple threads.

+6
source

Your program calls tcp() recursively after reconnecting. This is almost certainly not correct and will lead to the use of a resource (mainly a stack) at each shutdown.

You need to avoid the code passing the socket file descriptor (sockfd) by value in the function, as it will change after each new connection.

As a general principle, you can have a list of (two or more) hosts in order of preference. Then always try to create connections with those that have a higher preference than the one you are currently connecting to. Then, when the connection is established, close all other open sessions and switch to the new preferred connection.

Keep this encapsulated and return the current active sockfd for use by all other functions.

0
source

Source: https://habr.com/ru/post/958681/


All Articles