[VS] Aufgabe 1

Disclaimer: Dieser Thread wurde aus dem alten Forum importiert. Daher werden eventuell nicht alle Formatierungen richtig angezeigt. Der ursprüngliche Thread beginnt im zweiten Post dieses Threads.

[VS] Aufgabe 1
Hi,

kämpfe gerade gegen mein RPC messageboard.
Meine Struktur, die dem server übergeben wird (als parameter) sieht wie folgt aus (in messageboard.x):

typedef char *string_type;

struct parameter_struct {
[…]
string_type title;
string_type message;
};

Leider kommt im server als title und message nur Blödsinn an, wie z.B. ‘1®≈Aδε’ oder so.

Weiß jemand, was ich falsch mache???


Ohne mich damit wirklich beschäftigt zu haben: du bist sicher, dass du nicht nur den long int Wert des Pointers auf deinen String übers Netzwerk schickst?


Äh, verschicke nur den Pointer, stimmt. Was müsste ich denn sonst machen?
So:

struct parameter_struct {
[…]
char title[1024];
char message[1024];
};

?


ich werd mich erst am WE mit der Aufgabe beschäftigen - dann kann ich dir vielleicht mehr sagen


hast das Problem zwischenzeitlich gelöst oder brauchst noch einen Tip?


Nein, ich habe das Problem noch nicht gelößt, wollte erst meine Idee mit deiner Vergleichen. Bitte einen Tipp… :listen:


ich hatte das selbe problem, welches ich auch beseitigt hab in dem ich n festes char array gewählt habe.
hat jmd vielleicht ne idee wie man das ganze dynamisch machen koennte? also dynamische länge des message_typen bzw title_typen?


Also mit festen Arrays geht es natürlich, ist aber mächtig unschön. Außerdem ist es schwierig da eine vernünftige Länge zu wählen die nicht massig overhead produziert aber dafür im extremfall zu klein ist.

In der SUN RPC Beschreibung der Datentypen kann man auch arrays mit dynamischer Länge angeben. Außerdem gibt es einen Datentyp string.

Für den reinen Nachrichtentext würde ich string als Datentyp empfehlen. In der .h Datei kommt dann dort ein char * raus. Das rpc System überträgt dann den entsprechenden Inhalt des char arrays bis zum \0.

Um mehrere Nachrichten vom Server zu empfangen, lass ich mir ein dynamisches Array von Nachrichten zurückgeben. Die Anzahl der Elemente entspricht dann der geforderten (und verfügbaren) Anzahl von Nachrichten.

struct message
{
	int user_id;
	string title<>;
	string message_text<>;
};

struct answer
{
	struct message messages<>;
};

program MESSAGE_PROG{
        version MESSAGE_VERS{
                void POST(message) = 1;
		answer GET(int) = 2;
        } = 1;
} = 0x4711;

Bisschen doof finde ich, dass ich kein Datentyp<> bei den Funktionen als Rückgabewert angeben darf. Da hab ich mich mit dem struct answer herumgemogelt. Das finde ich aber bisschen unschön - kennt da jemand eine saubere Lösung?


sehr nett aber kannst du mal ganz kurz erläutern wie man ein

messages<> anspricht?

z.b.
answer.messages = messages[3]? (also stark vereinfacht)


Mit der Vorgabe erstellt er eine .h Datei. Dort sind dann die Structs definiert, die der rpcgen erzeugt hat. In dem Struct gibt es denn einen Pointer auf Messages und einen Integer in dem steht, wieviele Messages da sind. Mit diesen Informationen kannst dann Messages[ i ] verwenden.

also so in etwa:

struct answer{
  Messages *mess;
  int count;
}

habs jetzt selbst herausgefunden

also schaut ca. so aus das ganze

  struct answer* temp;

  note nachrichten[3]; // nachrichten befüllen
  temp->notes.notes_len = *n;
  temp->notes.notes_val = nachrichten;

  return temp;

sehr dumm wenn man ein notes<> erstellt
wird ein struct { u_int notes_len; char* notes_val; }
daraus generiert…
nachzulesen in der .h datei :stuck_out_tongue:

aber danke für die mühe


Genau, wobei so statische arrays wie dein Nachrichten[] dabei immer schlecht sind. Also vielleicht da lieber was hübsches mit malloc und so.


hab da jetzt frecherweise *n einfach rein für eben meine n letzten nachrichten mal schaun obs da fehler gibt später


Das n* ist nicht dein Problem. Du erzeugst wahrscheinlich in irgendeiner Funktion dein Nachrichten[] array. Das ist nur lokal in der Funktion gültig. Dann gibst du einen Pointer auf dieses Array zurück. Wenn die Funktion fertig ist, wird aber das Nachrichten[] array zerstört und dein Zeiger zeigt auf sonstwas.


Und wenn man das Array static macht?

Andere Frage: ich verstehe noch nicht, wie das mit den Strings funktioniert. Wo wird denn der Platz fuer die eigentlich Character allokiert? Nicht in meinem struct, in dem ich einen string definiere, oder?


Wie reagierst du dann, wenn der Benutzer mal die 1000 letzten Nachrichten haben will? Hällst du dann bei jedem Funktionsaufruf ein statisches Array mit 1000 Einträgen bereit? Also mein Server hat ne verkettete List für die Speicherung und der generiert für die Anfragen dynamisch die Arrays zur Übergabe.

Bei Nar Hallas Funktion wirds außerdem ein Problem geben, wenn mehr Nachrichten angefordert werden, als beim Server gespeichert sind.

Naja in jedem Struct ist ja ein char * Pointer. Wenn da Strings reinsollen, musst du entsprechend irgendwo Platz allozieren und dann den char * Pointer drauf zeigen lassen. Die RPC Funktionen sorgen dann dafür, dass die strings zum anderen Rechner kommen


OK, danke soweit.

response *
get_1_svc(int *argp, struct svc_req *rqstp)
{
        static response  result;

        message *res = (message *) malloc (sizeof (message));
        res->uid = mymess.uid;
        res->title = strdup (mymess.title);
        res->messagetext = strdup (mymess.messagetext);

        result.messages.messages_len = sizeof (message);
        result.messages.messages_val = res;

         return &result;
}

Hier habe ich jetzt soviel wie moeglich selber allokiert (was wahrscheinlich zuviel ist, aber egal) - trotzdem kriege ich einen Segmentation Fault. Warum?

Das ganze gibt testhalber nur eine Message zurueck, response und message sind in etwa so definiert wie bei dir oben. In mymess ist die gespeicherte Message auf dem Server gespeichert (globale Variable).


also result.messages.messages_len sind die Anzahl der Elemente in dem *messages Array. Also nix mit sizeof. Da muss in deinem Fall eine 1 stehen. Wahrscheinlich gehts deswegen schief, weil RPC versucht mehr als ein message struct zu senden, nach dem ersten das Array aber aufhört.


OK, nochmals danke, nach einigem Hin und Her funktioniert jetzt alles, wie es soll. Wo jetzt allerdings welcher Speicher zur Verfuegung gestellt wird, da habe ich noch ueberhaupt keinen Ueberblick. Aber ich gehe einfach mal davon aus, dass sich das RPC-System darum kuemmert :].
Auf Server-Seite brauche ich ja auch nicht aufzuraeumen, der Prozess laeuft ja endlos und ein DELETEPOST gibt es ja nicht.