UDP und select()

Gast #517957
Lesenswert?

Hi,

ich habe einen UDP Client für mein Board unter Linux programmiert, der
auch soweit ganz gut funktioniert.

Nun habe ich leider das Problem, dass das Programm anhält um nach dem
Senden aufgrund der Funktion recvfrom auf eine Antwort zu warten.

Ich würde gerne die Funktion select() verwenden um nach einer gewissen
timeout Zeit das warten auf eine Antwort abzubrechen und eine
Fehlermeldung auszugeben.

Wäre nett wenn mir jemand Tips geben kann wie ich das Programm verändern
muß einen Timeout zu erreichen.

Gruß
    OlFi

Source:
1
#include <stdio.h>
2
#include <stdlib.h>
3
#include <unistd.h>
4
#include <fcntl.h>
5
#include <string.h>
6
#include <sys/mman.h>
7
#include <signal.h>
8

9
#include <sys/types.h>
10
#include <sys/socket.h>
11
#include <netinet/in.h>
12
#include <arpa/inet.h>
13

14
#include "at91rm9200.h"
15

16
#define LPT_SERVER_IP 192.168.0.1
17
#define LPT_SERVER_PORT 5000
18

19
volatile u32 *pPIO_BASE;
20
char Page[]="Hello World";
21
int Char_position=0;
22
int Send=0;
23
char *szServer="192.168.0.1";
24
short nPort=LPT_SERVER_PORT;
25

26

27
int Client(void)  //Rückgabewert 0 wenn Selbsttest in Ordnung
28
{
29
//1. Einen Socket erstellen
30
int theSocket=0, Send_Test=0, ServerLen=0, nRet=0;
31
struct sockaddr_in saServer;
32
char Answer[256];
33

34
//AF_INET = Protokollfamilie  SOCK_DGRAM = UDP Datagramm Socket
35
theSocket=socket(AF_INET, SOCK_DGRAM, 0);
36

37
if (theSocket < 0) {
38
    printf("Creating socket... failed\n");
39
    return(1);
40
  }
41
else{
42
  printf("Creating socket... OK\n");
43
  }
44

45
//2. C Struktur mit Adressen füllen
46
saServer.sin_family= AF_INET;
47
saServer.sin_port= htons(nPort);
48
saServer.sin_addr.s_addr= inet_addr(szServer);
49

50
//3. Daten senden
51
Send_Test= sendto(theSocket, Page, strlen(Page), 0, &saServer, sizeof
52
(struct sockaddr));
53

54
if(Send_Test < 0){
55
  perror("sendto");
56
  printf("Error sending data\n");
57
  close(theSocket);
58
  return(1);
59
  }
60

61
//4. Warten auf Antwort vom Sender
62
memset(Answer, 0, sizeof(Answer));
63
ServerLen= sizeof(struct sockaddr);
64
nRet= recvfrom(theSocket, Answer, sizeof(Answer), 0, (struct sockaddr
65
*)&saServer, &ServerLen);
66
printf("Address %s answered: %s\n", inet_ntoa(saServer.sin_addr),
67
Answer);
68

69
//5. Socket beenden
70
close(theSocket);
71

72
return(0);
73
}
74

75
int main (void)
76
{
77
int result=1;
78

79
result=Client();
80

81
return (result);
82
}
#520654
Lesenswert?

Hallo OlFi,

das ist nicht schwer, schau hier:
1
bool feadiFunction( int fd, int timeout ) // timeout in sekunden
2
{
3
  fd_set fdset;
4
  FD_ZERO( &fdset );
5
  FD_SET( fd, &fdset );
6

7
  struct timeval tv_timeout = { timeout, 0 };
8

9
  int select_retval = select( fd+1, &fdset, NULL, NULL, &tv_timeout );
10

11
  if ( select_retval == -1 )
12
  {
13
    // ERROR!
14
  }
15

16
  if ( FD_ISSET( fd, &fdset ) )
17
    return true; // du kannst jetzt von fd lesen
18

19
  return false; // timeout
20
}

Diese Funktion fügst Du einfach vor recvfrom ein:
1
if ( feadiFunction( theSocket, 5 ) )
2
{
3
  nRet= recvfrom(theSocket, Answer, sizeof(Answer), 0, (struct sockaddr*)&saServer, &ServerLen);
4
}
5
else
6
{
7
  // timeout!
8
}

Gruß, Feadi

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren