Client IP bei UDP Sockets

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
Mandy
Beiträge: 9
Registriert: 03.11.2013 09:47:39

Client IP bei UDP Sockets

Beitrag von Mandy » 17.11.2013 21:48:35

Hallo Leute,

habt ihr eine Idee, warum im folgenden Script beim ersten Paket das ankommt die IP 0.0.0.0 ausgegeben wird?
Ab dem zweiten Durchlauf gibt die Zeile

Code: Alles auswählen

printf("Sender: %s\nDaten: %s\n", inet_ntoa(remoteAddr.sin_addr), datagram); 
die richtige Adresse aus.
Habe ich etwas falsch initialisiert?

Vielen Dank
Mandy

Code: Alles auswählen

static void *WarteAufKommando(void* val) {
  int rc;
	int hostSock;
  int remoteSock;
  struct sockaddr_in hostAddr;
	struct sockaddr_in remoteAddr;
//	char *remoteIP = "255.255.255.255";
	char datagram[512];
	socklen_t remoteLen;

  printf("WarteAufKommando gestartet (Adresse val:%p)\n", val);
  
	hostSock = socket(AF_INET, SOCK_DGRAM, 0);

	hostAddr.sin_family = AF_INET;
	hostAddr.sin_port = htons(PORT_NUMMER);
	hostAddr.sin_addr.s_addr = INADDR_ANY;

	rc = bind(hostSock, (struct sockaddr *)&hostAddr, sizeof(hostAddr));
  
  while(1)
  {
		bzero(datagram, 512);
		rc = recvfrom(hostSock, datagram, 512, 0, (struct sockaddr *)&remoteAddr, &remoteLen);
		datagram[rc] = 0;
    printf("Sender: %s\nDaten: %s\n", inet_ntoa(remoteAddr.sin_addr), datagram);    
   }

   printf("Thread wurde beendet\n");
   
   pthread_exit((void *)1);
      
   return NULL;
}

Gunman1982
Beiträge: 923
Registriert: 09.07.2008 11:50:57
Lizenz eigener Beiträge: MIT Lizenz

Re: Client IP bei UDP Sockets

Beitrag von Gunman1982 » 18.11.2013 13:35:13

Mandy hat geschrieben:

Code: Alles auswählen

		rc = recvfrom(hostSock, datagram, 512, 0, (struct sockaddr *)&remoteAddr, &remoteLen);
		datagram[rc] = 0;
Kenne den Grund zwar nicht warum du speziell eine 0 in deinem empfangenen buffer haben willst allerdings solltest du dir nochmal die return codes von recvfrom anschauen.
Wird beim ersten Durchgang denn ein valides datagram ausgegeben oder kommt da auch nur murks?

Mandy
Beiträge: 9
Registriert: 03.11.2013 09:47:39

Re: Client IP bei UDP Sockets

Beitrag von Mandy » 18.11.2013 20:57:26

Hallo Gunman,

ich schicke nur Text, der wird mit 0 abgeschlossen, und dann als string weiter verwendet.

Die Funktion gibt in der blockierenden Version immer die Länge der erhaltenen Daten zurück,
oder habe ich da was falsch interpretiert?

Die Daten selber sind auch beim ersten Durchlauf in Ordnung, einzig die IP ist leer..

Wollt noch hinzufügen: Für mich sind Linux und C zwei neue Welten... auch wenn ich schon viele Jahre vom Programmieren lebe :wink:

Danke
Mandy

Gunman1982
Beiträge: 923
Registriert: 09.07.2008 11:50:57
Lizenz eigener Beiträge: MIT Lizenz

Re: Client IP bei UDP Sockets

Beitrag von Gunman1982 » 18.11.2013 23:28:49

Mandy hat geschrieben:Hallo Gunman,

ich schicke nur Text, der wird mit 0 abgeschlossen, und dann als string weiter verwendet.
Du meinst der Text soll mit einem 0-byte terminiert werden, das wäre dann '\0' nicht 0. In deinem code schreibst du ne integer 0 an die Stelle im Speicher.
Mandy hat geschrieben: Die Funktion gibt in der blockierenden Version immer die Länge der erhaltenen Daten zurück,
oder habe ich da was falsch interpretiert?
Sofern kein Fehler auftritt, ansonsten gibs -1, was zu einem segfault führen würde. Gleiche wenn die Menge der empfangenen bytes 512 erreicht.
Mandy hat geschrieben: Die Daten selber sind auch beim ersten Durchlauf in Ordnung, einzig die IP ist leer..
Könnte daran liegen das remoteLen beim ersten Aufruf noch nich initialisiert ist. Versuch mal ein

Code: Alles auswählen

remoteLen=sizeof(remoteAddr);
vor der while Schleife.

Und noch 1-2 Punkte:
1. bzero ist deprecated, man sollte memset nutzen, in diesem Fall mit '\0' als char.
2. Da du das datagram eh mit \0 füllst (durch bzero) kannst du dir den

Code: Alles auswählen

datagram[rc]='\0'
sparen. Solltest dann aber bei recv statt 512 die länge 511 nutzen. Somit ist das letzte Zeichen im datagram garantiert '\0'
3. Du solltest den return code von bind prüfen und nur wenn dieser 0 ist in die while Schleife gehen.

Mandy
Beiträge: 9
Registriert: 03.11.2013 09:47:39

Re: Client IP bei UDP Sockets

Beitrag von Mandy » 19.11.2013 22:48:26

Hallo Gunman,

das hat geholfen:

Code: Alles auswählen

remoteLen=sizeof(remoteAddr);
Und vielen Dank noch für deine Hinweise.
Sind schon umgesetzt. :THX:

Noch eine Verständnisfrage:
Was ist der Unterschied zwischen '\0' und 0?
Speziell bei memset ist mir das überhaupt nicht klar.

Danke
Mandy

wanne
Moderator
Beiträge: 7550
Registriert: 24.05.2010 12:39:42

Re: Client IP bei UDP Sockets

Beitrag von wanne » 19.11.2013 23:28:49

Mandy hat geschrieben:Was ist der Unterschied zwischen '\0' und 0?
Der Datentyp. Gewisse Operatoren verhalten sin je nach datentyp anders. Itraditionellem C89 ist das noch relativ irrelevant. Da es in C kein überladen gibt und sich nur einige eingebauten operatoren unterscheiden.
In C++ gibt's das häufiger (Weswegen moderne C-Compiler im Normalfall zumindest warnen, wen ein falscher datentyp in einen anderen geschrieben wird.):

Code: Alles auswählen

std::cout << "anfang " << '\0' << " ende" << endl;
Führt zu der Ausgabe:

Code: Alles auswählen

anfang  ende

Code: Alles auswählen

std::cout << "anfang " << 0 << " ende" << endl;

Code: Alles auswählen

anfang 0 ende
Bei C89 wird im normalfall impliziert gecastet.
rot: Moderator wanne spricht, default: User wanne spricht.

Antworten