Probleme bei Socket Programmierung- bitte um Hilfe

drooper

Grünschnabel
Hallo erstmal,

bin neu hier im Forum und ich hoffe ihr könnt mir vielleicht weiterhelfen, denn ich selbst kann es anscheinend nicht :(

Ich möchte einen kleinen Chat testweise programmieren und scheitere bereits daran, dass ich die eingegebenen Zeichen z.B. eines Clients nicht korrekt einlesen kann. Arbeite mit send() und recv() und muss ja in beiden Fällen einen u.a. Zeiger vom Typ char übermitteln. Nun kenne ich mich mit Zeigern nicht wirklich gut aus und habe Probleme die Zeichenkette mittels scanf() einzulesen. So schaut es momentan aus:

char *msg;
....
printf("Eingabe: ");
scanf("%s,msg);
...

Wenn ich es so versuche, stürzt der Client ab. Hab auch schon einiges Probiert, doch leider ohne Erfolg. Komisch ist, dass es zum Beispiel klappt wenn ich es ohne Einlesen mit msg="...." mache. Ist das denn nicht das gleiche?

Vielen Dank schon mal im Voraus!

lg
Marcus
 
Hallo,
--schnipp
char *msg;
....
printf("Eingabe: ");
--schnipp

was passiert denn dort wo die 3 Punkte stehen? Ein Zeiger des Typs char * zeigt auf eine Anfangsadresse eines Speicherbereichs wo einzelne Zeichen (vom Typ char) hinterenander abgelegt sind. Um diese Zeichen darein speichern zu können musst du dafür vorher (also bevor du was reinschreibst) auch Speicher alloziieren. Entweder du tust das in dem du den Speicher statisch auf dem Stack anlegst:
Code:
char msg[1024];
oder dynamisch auf dem heap:
Code:
char *msg;
msg = (char *) malloc (sizeof(char) * 1024);
...
free (msg);
Bei letzterer Variante musst du den Speicher manuell wieder freigeben. Bei ersterer Variante geschieht das automatisch wenn der Aufrufstack wieder abgebaut wird.

Gruß,
RedWing
 
Hallo,
Hey,

was mir auch aufgefallen ist, das du bei deinem scanf()

noch die "Speicheradresse zuweisen musst, also den "&" Operator vor das "msg" sonst kann das scanf() nichts einlesen.
Code:
scanf("%s",&msg)

Gruß Dorschty

Muss er nicht.

msg selber ist ja schon eine Speicheradresse, nämlich ein Zeiger.

Gruß,
RedWing
 
Oh stimmt, hast recht... hatte verschwitzt, das es ein Zeiger war! :-(
Sorry, ich nehm alles zurück und behaupte das Gegenteil! :)
Allerdings sollte er trotzdem die Hochkommata komplett setzen!


in

Code:
scanf("%s",msg);

:p;-)

Gruß
Dorschty
 
Danke, dass ging ja schnell!

@RedWing
kannst du mal den genauen Code posten:

char *msg[1024] geht ja nicht. Muss ich noch eine zusätzliche Variable einführen, wie zum Beispiel so:

char temp[255];
char *msg = &temp;

Funktioniert auch nicht, aber wieso? Ist char ne Ausnahme, denn mit anderen Zeigern z.B. vom typ int t es.

lg
Marcus
 
Hallo,

Danke, dass ging ja schnell!

@RedWing
kannst du mal den genauen Code posten:

char *msg[1024] geht ja nicht. Muss ich noch eine zusätzliche Variable einführen, wie zum Beispiel so:

char temp[255];
char *msg = &temp;

Funktioniert auch nicht, aber wieso? Ist char ne Ausnahme, denn mit anderen Zeigern z.B. vom typ int t es.

lg
Marcus

Versuchs doch mal so:
C:
char msg[1024];
scanf ("Insert string: %s", msg);
printf ("%s\n", msg);

Gruß
 
Ich hab es mit der dynamischen Speicherreservierung gemacht, wie du am Anfang gepostest hast. Lese es mit cin.getline() ein. Klappt wunderbar- danke dafür.
Doch nun bin ich schon wieder beim nächsten Problem angelangt. Bei mir kann immer nur der Server oder der Client der Fragenden bzw. Antwortende sein. So kann z.B. der Client nicht mehrere Daten hintereinander senden. Weiß noch nicht wie ich das lösen kann. Der Client sendet via send() und geht dann im Programm weiter bis recv() und wartet dann ja auf das zurückkommende Socket samt Inhalt. Ich kann quasi erst wieder senden, wenn ich auch was empfangen habe. Ist der Chat denn mittels nur einem Socket überhaupt realisierbar? Hat jemand Lösungsvorschläge?

lg
Marcus
 
Hallo!

das lässt sich prinzipiell nur mit Threads lösen. Du musst nämlich Schreiben und Lesen gleichzeitig können. Und außerdem willst du, wie du schon sagtest, nicht immer darauf warten bis der andre dir was geschrieben hat bevor du was schreiben kannst.

Folgender Pseudocode für Server und Clientseite sollte dir das prinzipielle vorgehen zeigen:

Code:
void
receiver_task (void)
{
    while (1)
      {
        char recv_buffer[1024];
        recv (socket_handle, recv_buffer, sizeof (recv_buffer));
        print ("Message received: %s\n", recv_buffer);
      }
}

void
sender_task (void)
{
    while (1)
      {
        char send_buffer[1024];

        scan ("Insert message to send: %s", send_buffer);
        send (socket_handle, send_buffer, sizeof (send_buffer));
      }
}

connect_socket ();
/* starte beide Tasks "nebenläufig" */
start_task (sender_task, 0);     
start_task (receiver_task, 0);

Wie man das dann konkret realisiert (also die Nebenläufigkeit) hängt vom Betriebssystem und der Programmierumgebung ab.
Schau mal da:
http://de.wikipedia.org/wiki/Thread_(Informatik)

HTH,
RedWing
 
Zuletzt bearbeitet:
Zurück