Reputation: 2103
I'm using Ubuntu and I have a C/C++ application which uses WxWidgets and sends a string over TCP. It works pretty fine only if the router and the connection are OK, otherwise it gets stuck and I need to manually quit the application.
I call the function in this way:
SendCommand ptr;
if ( ptr.sendcommand(16,16,1) ){
printf("Porta Aperta\n");
} else {
printf("Errore di comunicazione - porta non aperta\n");
}
and this is the function:
int SendCommand::sendcommand(int relay_on, int relay_off, int stop){
printf("eseguo la funzione nella classe\n");
std::array<uint8_t, 8> command1;
std::array<uint8_t, 8> command2;
switch(relay_on){
case 16: command1 = {0x58, 0x01, 0x12, 0x00, 0x00, 0x00, 0x10, 0x7B}; // switch on the relay 16
break;
}
switch(relay_off){
case 16: command2 = {0x58, 0x01, 0x11, 0x00, 0x00, 0x00, 0x10, 0x7A}; // switch off the relay 16
break;
}
int sockfd, n;
struct sockaddr_in servaddr;
std::string serveraddr = "192.168.1.4";
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if ( sockfd < 0 )
{
cerr << "Error creating socket! " << strerror(errno) << endl;
return -1;
}
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = inet_addr(serveraddr.c_str());
servaddr.sin_port = htons(3000);
if (connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0)
{
cerr << "Error connecting socket!" << strerror(errno) << endl;
close(sockfd);
return -1;
}
//Relay #14 per porta bilancia
printf("Apro la porta\n");
int bytes_to_send1 = sizeof(command1);
int bytes_to_send2 = sizeof(command2);
int bytes_sent1 = 0;
int bytes_sent2 = 0;
do
{
n = send(sockfd, command1.data() + bytes_sent1, bytes_to_send1 - bytes_sent1, 0);
if ( n < 0 )
{
cerr << "Error writing to socket!" << strerror(errno) << endl;
close(sockfd);
}
bytes_sent1 += n;
}
while (bytes_sent1 < bytes_to_send1);
n=0;
sleep(stop);
do
{
n = send(sockfd, command2.data() + bytes_sent2, bytes_to_send2 - bytes_sent2, 0);
if ( n < 0 )
{
cerr << "Error writing to socket!" << strerror(errno) << endl;
close(sockfd);
}
bytes_sent2 += n;
}
while (bytes_sent2 < bytes_to_send2);
close(sockfd);
n=0;
return 1;
}
Thanks to the suggestions received in a previous topic, I'm using the notation std::array<uint8_t, 8> command1;
to define the arrays for the content to send over the net, but I cannot find a solution to let my program flows correctly even if there are problems on the network.
I tried to use threads or fork() and it works, but is there any other easier solution for this?
P.S. When it get stuck because there is not internet connection, it blocks here:
if (connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0)
{
cerr << "Error connecting socket!" << strerror(errno) << endl;
close(sockfd);
return -1;
}
it never enters the if condition.
Upvotes: 0
Views: 90
Reputation: 1156
Several options
For 2 - try using std threads, should be easy to use (you can also go for async + lambda and simplify control flow using futures).
That way code will look and will be more easier to read.
For 3 & 4 - you need to set socket non blocking and do a poll (either through select or epoll) - see fnctl(.., O_NONBLOCK ..) select(). And if you get no error, then you can use the socket as it is (or maybe return it from async and get in future).
Upvotes: 1