Forum: PC-Programmierung UDP und select()


von OlFi (Gast)


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
}

von Feadi F. (feadi)


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

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.