Verwirrung um winsock mit struct und pointer
-
Hallo,
ich bin ein bisschen verwirrt bezüglich der Winsock Kommunikation und dem Speichern bzw. Lesen der Daten in bzw aus einer Struktur.
Ich habe eine data.h mit den zwei Strukturen:
data.h
... struct request { unsigned char ReqType; #define ReqNone 0 #define ReqBook 'B' #define ReqStorn 'S' unsigned FlNr; /* Flight Number */ unsigned SeNr; /* Seat Number (== 0) no Special Seat */ char name[32]; struct ExpSeat SeatWanted; /* Type of Seat wanted */ }; struct answer { unsigned char AnswType; #define AnswNone 0 #define AnswOk 'O' #define AnswWarn 'W' /* example: Seat not available */ #define AnswErr 0xFF unsigned FlNr; unsigned SeNo; #define ErrNo SeNo /* Are identical */ };Weiterhin habe ich in der Server Datei folgendes
server.c
#include <data.h> ... //Prototypen static struct request req; ... struct request *getRequest() { ... long rc; // Verbindung annehmen rc=accept(s,NULL,NULL); while (1){ // Warte am Socket auf Daten und speichere sie in req ab recv(s,(char *)&req, sizeof(struct request), 0); { printf ("error recvfrom"); return(0); }; return(&req); } }; int sendAnswer(struct answer *answ) { // Schreibe die uebergebene Antwort answ an das Socket ***/ send(s,(char *)&answ,sizeof(struct answer),0); return(1); };und in der Client Daten folgendes:
client.c
#include <data.h>; ... //Prototypen static struct answer answ; ... struct answer *DoRequest(struct request *req) { ... // Schreibe in das Socket die Anfrage req send(s,(char *)&req,sizeof(struct request),0); while (1){ // Lese die Antwort vom Socket und speichere sie in answ ab recv(s,(char *)&answ,sizeof(struct answer),0); { printf ("error recvfrom"); return(0); }; break; } //schließe Socket closesocket(s); return(&answ); };Der Compiler läuft ohne Probleme durch und ich kann den Server (server.exe) starten. Winsock wird gestartet, der Socket wird erstellt und an den Port gebunden und er geht in den listen Mode.
Wenn ich dann aber den Client starte wird bei ihm auch Winsock gestartet, der Socket erstellt und er verbindet sich mit dem Server.
Sofort danach bekomme ich vom Debugger die Fehlermeldung: Unbehandelte Ausnahme bei 0x0042ed11 in server.exe: 0xC0000005: Zugriffsverletzung beim Lesen an Position 0x00000000.Ich denke das irgendwas mit dem recv(..) und dem send(..) und dem speichern/lesen aus der Structur nicht funktioniert. Ich sehe leider nicht was!
Hat jemand eine Ahnung?
Danke,
Andreas
-
Versuche mal mit Debuggen heraus zu finden wo das passiert.
Außerdem sieht das sehr stark nach reinem C aus.mfg.
-
Hi !
Die Funktion send hätte gern als zweiten Paramter den Typ:
const char FAR * buf,
und die Funktion recv gibt sich mit einem char FAR * buf zufrieden.
Weil deine Parameter vom Typ static struct und als char* gecastet sind, geht das schief.Edit: Um in der Zeile 13 einen Namen empfangen zu können, müsste der Aufruf so aussehen:
recv(s, req.name, sizeof(req.name), 0);Gruß,
p.
-
Hallo,
danke erstmal für die Antworten.
Wie kann ich es bewerkstelligen das der ganze Inhalt der Struktur empfangen wird und nicht nur der Name?Dnake,
Andreas
-
Für die komplette Struktur kannst du es mit deiner cast- Methode machen,
wenn du für genug Puffer sorgst.Der dritte Parameter in deiner recv Funktion z.B. berücksichtigt nicht, das in der Struktur struct request noch eine weitere Struktur enthalten ist, nämlich
struct ExpSeat.Darum müsstest du den dritten Parameter erweitern:
... ,sizeof(struct request) + sizeof( struct ExpSeat ), ; ...Die defines kannst du aus deinen Strukturen rausschmeissen und global definieren, weil sie sich nicht kapseln lassen und auch nicht übertragen werden.
Sie haben keinen Einfluss auf die Größe der Strukturen.Grüße,
p.
-
proggingmania schrieb:
Hi !
Die Funktion send hätte gern als zweiten Paramter den Typ:
const char FAR * buf,
und die Funktion recv gibt sich mit einem char FAR * buf zufrieden.
Weil deine Parameter vom Typ static struct und als char* gecastet sind, geht das schief.static heisst hier: nur in dieser Uebersetzungseinheit sichtbar, d. h. auf req
kann nicht aus anderen Uebersetzungseinheiten aus zugegriffen werden.Edit: Um in der Zeile 13 einen Namen empfangen zu können, müsste der Aufruf so aussehen:
recv(s, req.name, sizeof(req.name), 0);Er sendet aber die ganze Struktur 'request'. Was will er dann mit mit Daten
in 'name'?proggingmania schrieb:
Für die komplette Struktur kannst du es mit deiner cast- Methode machen,
wenn du für genug Puffer sorgst.Er hat ja genug Puffer, denn er hat ja eine Instanz von req erzeugt.
Der dritte Parameter in deiner recv Funktion z.B. berücksichtigt nicht, das in der Struktur struct request noch eine weitere Struktur enthalten ist, nämlich
struct ExpSeat.Darum müsstest du den dritten Parameter erweitern:
... ,sizeof(struct request) + sizeof( struct ExpSeat ), ; ...Nein das musst du natuerlich nicht. Die Groesse innerer Strukturen wird korrekt
in die Berechnung mit einbezogen. Dieses Problem haettest du nur, wenn
SeatWanted ein Zeiger waere.Die defines kannst du aus deinen Strukturen rausschmeissen und global definieren, weil sie sich nicht kapseln lassen und auch nicht übertragen werden.
Sie haben keinen Einfluss auf die Größe der Strukturen.Definiere "uebertragen werden". Ansonsten ist es natuerlich korrekt. Aber man
"sieht" hiermit eine gewisse Zugehoerigkeit der Defines. Allerdings nur, wenn
man sich die Deklaration anschaut, im Quellcode selber geht sie verloren.while (1){ // Warte am Socket auf Daten und speichere sie in req ab recv(s,(char *)&req, sizeof(struct request), 0); { printf ("error recvfrom"); return(0); }; return(&req); }Schau dir den Code mal genau an. Wann geht er in den inneren Block rein und
was gibt er in diesem Falle zurueck? Was passiert danach mit dem Rueckgabewert?
Versuchst du auf diesen zuzugreifen? In client.c tust du das uebrigens auch.
Sieht nach einer vergessenen if-Bedingung aus.Lass den Code mal im Debug-Modus laufen und mach einen Backtrace.
gruss
v R
-
virtuell Realisticer schrieb:
Nein das musst du natuerlich nicht. Die Groesse innerer Strukturen wird korrekt
in die Berechnung mit einbezogen. Dieses Problem haettest du nur, wenn
SeatWanted ein Zeiger waere.Ja, stimmt, sorry.
Die Zeilerecv(s,(char *)&req, sizeof(struct request), 0);ist also durchaus korrekt.