Witam,
Znając C uczę się C++ i chcę wykorzystać wyjątki do następującej rzeczy:
- 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ę).
- 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.
- 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;
}