C++ i użycie wyjątku do obsługi SIGPIPE

0

Witam,
Znając C uczę się C++ i chcę wykorzystać wyjątki do następującej rzeczy:

  1. Mam aplikację echa (najprostsze co może być: klient i serwer, klint wysyła tekst, serwer odsyła ten sam tekst zamieniony na wielką literę).
  2. W przypadku, gdy serwer zakończy pracę, a klient wciąż jest podłączony w momencie wysyłania klient zostanie zabity przez sygnał SIGPIPE, chyba że go ignoruje. Chcę tego uniknąć bo spróbować użyć czegoś nowego - wyjątku. W tym celu polecenie send zostaje wrzucone do bloku try, a komunikaty i polecenie zakończenia polecenia zostają wrzuconego do bloku catch. To nie działa, aplikacja wciaż umiera od SIGPIPE.
  3. Czy wyjątki zadziałają tylko ze specjalnymi funkcjami, które wypluwają wyjątek za pomocą throw i nie nadają się do użycia we wielu sytuacjach (trochę jakby były przereklamowane jak głupio by to nie brzmiało)?

Kod:

#include <iostream>
#include <string>
#include <cstdlib>
#include <cctype>
#include <cstdio>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h> // struct sockaddr_in
#include <arpa/inet.h>
#include <unistd.h>

using namespace std;

/*
 *  Simple echo client to test exceptions in C++.
 */

#define PORT 1000

int main()
{
  int sockfd;
  sockaddr_in server = {AF_INET, PORT};
  pid_t pid;
  
  server.sin_addr.s_addr = inet_addr("127.0.0.1");
  
  
  if( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1 ) {
    cerr << "Socket call failed" << endl;
    exit(1);
  }
  
  // connect to server
  if( connect(sockfd, (sockaddr*) &server, sizeof(sockaddr_in)) == -1 ) {
    cerr << "connect call failed" << endl;
    exit(1);
  }
  
  // send and recieve data
  char c, rc;
  while(1) {
    c = getchar();
    try {
      send(sockfd, &c, 1, 0);
    } catch(string w) {
      // shouldn't it display?
      cerr << "Error sending data!" << endl;
      cerr << "Probably SIGPIPE - server died!" << endl;
      exit(1);
    }
    recv(sockfd, &rc, 1, 0);
    cout << rc << endl;
  }
  
  return 0;
}

Serwer:

#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cctype>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h> // struct sockaddr_in
#include <unistd.h>

using namespace std;

/*
 *  Simple echo server to test exceptions in C++.
 */

#define PORT 1000

int main()
{
  int sockfd, newsockfd;
  sockaddr_in server = {AF_INET, PORT, INADDR_ANY};
  pid_t pid;
  
  if( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1 ) {
    cerr << "Socket call failed" << endl;
    exit(1);
  }
  
  // bind socket with server address
  if( bind(sockfd, (sockaddr*) &server, sizeof(sockaddr_in)) == -1 ) {
    cerr << "bind call failed" << endl;
    exit(1);
  }
  
  // start listen
  if( listen(sockfd, 5) == -1 ) {
    cerr << "listen call failed" << endl;
    exit(1);
  }
  
  // start accept loop
  char c;
  for(; ;) {
    if( (newsockfd = accept(sockfd, NULL, NULL)) == -1) {
      cerr << "accept call failed" << endl;
      continue;
    }
    
    // create child for new connection
    switch(pid = fork()) {
      case 0:
	// child code: recieve data and send them back
	while( recv(newsockfd, &c, 1, 0) > 0 ) {
	  cout << c;
	  c = toupper(c);
	  // send it back!
	  send(newsockfd, &c, 1, 0);
	}
	break;
      default:
	// parent code
	break;
    }
  }
  
  return 0;
}
0

SIGPIPE to nie wyjątek tylko sygnał. Żeby łapać sygnał musisz użyć http://linux.die.net/man/2/signal

0

Ok, czyli wyjątki mogą być użyte tylko do błędów rzuconych za pomocą polecania throw?

Dzięki.

0

Tak.

1 użytkowników online, w tym zalogowanych: 0, gości: 1