Studium, Ausbildung und Beruf
 StudiumHome   FAQFAQ   RegelnRegeln   SuchenSuchen    RegistrierenRegistrieren   LoginLogin

socket programmierung unter linux
Neues Thema eröffnen   Neue Antwort erstellen
Foren-Übersicht -> Informatik-Forum -> socket programmierung unter linux
 
Autor Nachricht
Box
Senior Member
Benutzer-Profile anzeigen
Senior Member


Anmeldungsdatum: 29.12.2005
Beiträge: 1002

BeitragVerfasst am: 17 März 2008 - 19:03:15    Titel: socket programmierung unter linux

Grüß Euch, ich verstehe nicht ganz den Ablauf der folgenden 2 Programme. Es handelt sich hierbei um Standard-Programme wie sie in fast jedem Buch zu finden sind. Die beiden Programme erzeugen folgende Ausgaben:

Server:
Code:

Socket wurde angelegt
Ein Client (127.0.0.1) ist verbunden ...
Nachricht zum Versenden: Erste Nachricht
1
2
3
4


Client:
Code:
Socket wurde angelegt
Verbindung mit dem Server (127.0.0.1) hergestellt
Nachricht erhalten: Erste Nachricht

Nachricht zum Versenden:


Das Problem ist, dass die Nachricht gesendet wird bevor die Ausgabe mit printf erzeugt wird. Danach geht es merkwürdig weiter:

Client:
Code:
Socket wurde angelegt
Verbindung mit dem Server (127.0.0.1) hergestellt
Nachricht erhalten: Erste Nachricht

Nachricht zum Versenden: Erste Antwort
Nachricht erhalten: 1

Nachricht zum Versenden:


Server:
Code:
Socket wurde angelegt
Ein Client (127.0.0.1) ist verbunden ...
Nachricht zum Versenden: Erste Nachricht
1
2
3
4
Eingabe der Nachricht beendet.Nachricht empfangen: Erste Antwort

Nachricht zum Versenden:


Die Ausgabe "Eingabe wurde beendet" wird ausgegeben, nach dem vom client eine Nachricht empfangen wurde. Das entspricht aber alles nicht der Reihenfolge im Quelltext. Auch das er weiter Eingaben entgegennimmt (1,2,3,4), obwohl er die erste Eingabe schon längst abgeschickt hat und die dann auch nach und nach an den Socket schickt, verwirrt mich. Ich blick einfach nicht ganz durch wie da die Reihenfolge ist. Ich verwende doch kein non-blocking oder so.

Ich bin für jeden Tipp dankbar.

Hier der Quelltext:

Code:
#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define BUF 1024

int main (int argc, char **argv) {
  int create_socket;
  char *buffer = malloc (BUF);
  struct sockaddr_in address;
  int size;

  if( argc < 2 ){
     printf("Usage: %s ServerAdresse\n", *argv);
     exit(EXIT_FAILURE);
  }

  printf ("\e[2J");
  if ((create_socket = socket (AF_INET, SOCK_STREAM, 0)) > 0)
    printf ("Socket wurde angelegt\n");

  address.sin_family = AF_INET;
  address.sin_port = htons (15000);
  inet_aton (argv[1], &address.sin_addr);

  if (connect ( create_socket,
                (struct sockaddr *) &address,
                sizeof (address)) == 0)
    printf ("Verbindung mit dem Server (%s) hergestellt\n",
       inet_ntoa (address.sin_addr));
  do {
      size = recv(create_socket, buffer, BUF-1, 0);
      if( size > 0)
         buffer[size] = '\0';
      printf ("Nachricht erhalten: %s\n", buffer);
      if (strcmp (buffer, "quit\n")) {
         printf ("Nachricht zum Versenden: ");
         fgets (buffer, BUF, stdin);
         send(create_socket, buffer, strlen (buffer), 0);
       }
  } while (strcmp (buffer, "quit\n") != 0);
printf("Verbindung zum Server wurde beendet.");
  close (create_socket);
  return EXIT_SUCCESS;
}


Code:
 
/* server.c */
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define BUF 1024

int main (void) {
  int create_socket, new_socket;
  socklen_t addrlen;
  char *buffer = malloc (BUF);
  ssize_t size;
  struct sockaddr_in address;
  const int y = 1;

  printf ("\e[2J");
  if ((create_socket = socket (AF_INET, SOCK_STREAM, 0)) > 0)
    printf ("Socket wurde angelegt\n");

  setsockopt( create_socket, SOL_SOCKET,
              SO_REUSEADDR, &y, sizeof(int));

  address.sin_family = AF_INET;
  address.sin_addr.s_addr = INADDR_ANY;
  address.sin_port = htons (15000);
  if (bind ( create_socket,
             (struct sockaddr *) &address,
             sizeof (address)) != 0) {
    printf( "Der Port ist nicht frei - belegt!\n");
  }
  listen (create_socket, 5);
  addrlen = sizeof (struct sockaddr_in);

  while (1) {
     new_socket = accept ( create_socket,
                           (struct sockaddr *) &address,
                           &addrlen );
     if (new_socket > 0)
      printf ("Ein Client (%s) ist verbunden ...\n",
         inet_ntoa (address.sin_addr));
     do {
        printf ("Nachricht zum Versenden: ");
        fgets (buffer, BUF, stdin);
        printf("Eingabe der Nachricht beendet.");
        send (new_socket, buffer, strlen (buffer), 0);
        size = recv (new_socket, buffer, BUF-1, 0);
        if( size > 0)
           buffer[size] = '\0';
        printf ("Nachricht empfangen: %s\n", buffer);
     } while (strcmp (buffer, "quit\n") != 0);
        printf("Die Verbindung zum Client: %s wurde beendet.\n", inet_ntoa(address.sin_addr));
        close (new_socket);
  }
  close (create_socket);
  return EXIT_SUCCESS;
}
Hirmick
Full Member
Benutzer-Profile anzeigen
Full Member


Anmeldungsdatum: 28.12.2007
Beiträge: 473
Wohnort: Göttingen

BeitragVerfasst am: 17 März 2008 - 21:06:11    Titel:

Hat bestimmt irgendwas mit der Pufferung von stdin zu tun ... hatte damit auch schon probleme. Versuch mal flushs einzubauen ... Und sonst: Debuggen Wink

Vlt. ist es auch ein technisches Problem, also dass du den Src änderst, der Linker aber alte Dateien einlinkt etc. Was nutzt du ? gcc+make, irgendeine Form von autoconf oder eine IDE ?
Box
Senior Member
Benutzer-Profile anzeigen
Senior Member


Anmeldungsdatum: 29.12.2005
Beiträge: 1002

BeitragVerfasst am: 18 März 2008 - 22:09:27    Titel:

Hallo Hirmick,

ich habs jetzt. Du hattest recht; es hatte mit der Pufferung zu tun. fgets schien die EIngabe nicht ordentlich mit \0 zu terminieren und in den Beispiel-Programmen wurde erst bei erfolgreichem Empfang der Antwort mit \0 terminiert (zusätzlich wurde noch der gleiche buffer fürs senden und empfangen verwendet...). Anscheinend hat fgets die Ausgabe von printf "blockiert" und nach dem Empfang (und der Terminierung mit \0) erst die printf's ausgeführt.

Außerdem scheint send dann auch immer nur bis zum \n gesendet zu haben. Sinnvoll wäre es fürs senden und empfangen separate buffer zu verwenden, die direkt mit \0 zu terminieren und nach dem Senden jeweils zu leeren.

Jedenfalls kriege ich jetzt folgende Ausgabe:
Server:
Zitat:

Socket wurde angelegt
Ein Client (127.0.0.1) ist verbunden ...
Nachricht zum Versenden: Erste Nachricht
Eingabe der Nachricht beendet.
Nachricht gesendet
Warte auf neue Nachricht vom Client
Nachricht empfangen: Erste Antwort

Nachricht zum Versenden: Antwort erhalten
Eingabe der Nachricht beendet.
Nachricht gesendet
Warte auf neue Nachricht vom Client


Client:
Zitat:

Socket wurde angelegt
Verbindung mit dem Server (127.0.0.1) hergestellt
Nachricht erhalten: Erste Nachricht

Nachricht zum Versenden: Erste Antwort
Nachricht erhalten: Antwort erhalten

Nachricht zum Versenden:


Bleibt mir nur noch Danke für den Tipp mit der Pufferung zu sagen. Smile



Geänderter Quellcode (vielleicht hilfts irgendwann jemanden der mit google nach einer Lösung sucht. *g*):
client.c
Code:
do {
      size = recv(create_socket, buffer2, BUF-1, 0);
      if( size > 0)
         buffer2[size] = '\0';
      printf ("Nachricht erhalten: %s\n", buffer2);
      if (strcmp (buffer, "quit\n")) {
         printf ("Nachricht zum Versenden: ");
         fgets (buffer, BUF, stdin);
    buffer[strlen(buffer)]='\0';
         send(create_socket, buffer, strlen (buffer), 0);
       }
  } while (strcmp (buffer, "quit\n") != 0);


server.c

Code:

 do {
        printf ("Nachricht zum Versenden: ");
        fgets (buffer2, BUF, stdin);
   buffer2[strlen(buffer2)]='\0';
   printf("Eingabe der Nachricht beendet.\n");
        send (new_socket, buffer2, strlen (buffer2), 0);
        printf("Nachricht gesendet\n");
   printf("Warte auf neue Nachricht vom Client\n");
   size = recv (new_socket, buffer, BUF-1, 0);
        if( size > 0)
           buffer[size] = '\0';
        printf ("Nachricht empfangen: %s\n", buffer);
     } while (strcmp (buffer, "quit\n") != 0);
Beiträge der letzten Zeit anzeigen:   
Foren-Übersicht -> Informatik-Forum -> socket programmierung unter linux
Neues Thema eröffnen   Neue Antwort erstellen Alle Zeiten sind GMT + 1 Stunde
Seite 1 von 1

 
Gehe zu:  
Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.

Chat :: Nachrichten:: Lexikon :: Bücher :: Impressum