Winsock Problem bei Datenübertragung
-
Hallo Leute. Ich hab mich mal an die Winsock Programmierung gewagt und nach einem Tutorial von www.c-worker.ch mir einen Client und einen Server geschrieben. Leider wird am Ende der String nicht übertragen, stattdessen gibt mir das Konsolenfenster viele "weiße Striche" (wusste jetzt nicht, wie ich das sonst beschreiben soll) aus.
SERVER:
#include <windows.h> #include <cstdio> #include <conio.h> using namespace std; //Prototypen int startWinsock(); int main() { int rc; SOCKET acceptSocket; SOCKET connectedSocket; SOCKADDR_IN addr; char buf[256]; SOCKET s; // Winsock starten rc=startWinsock(); if(rc!=0) { printf("Fehler: startWinsock, fehler code: %d\n",rc); return 1; } else { printf("Winsock gestartet!\n"); } // Socket erstellen acceptSocket=socket(AF_INET,SOCK_STREAM,0); if(acceptSocket==INVALID_SOCKET) { printf("Fehler: Der Socket konnte nicht erstellt werden, fehler code: %d\n",WSAGetLastError()); return 1; } else { printf("Socket erstellt!\n"); } memset(&addr,0,sizeof(SOCKADDR_IN)); addr.sin_family=AF_INET; addr.sin_port=htons(12345);//port addr.sin_addr.s_addr=INADDR_ANY; rc=bind(acceptSocket,(SOCKADDR*)&addr,sizeof(SOCKADDR_IN)); if(rc==SOCKET_ERROR) { printf("Fehler: bind, fehler code: %d\n",WSAGetLastError()); return 1; } else { printf("Socket an port 12345 gebunden\n"); } rc=listen(acceptSocket,10); if(rc==SOCKET_ERROR) { printf("Fehler: listen, fehler code: %d\n",WSAGetLastError()); return 1; } else { printf("acceptSocket ist im listen Modus....\n"); } connectedSocket=accept(acceptSocket,NULL,NULL); if(connectedSocket==INVALID_SOCKET) { printf("Fehler: accept, fehler code: %d\n",WSAGetLastError()); return 1; } else { printf("Neue Verbindung wurde akzeptiert!\n"); } rc=recv(s,buf,256,0); printf(buf); getchar(); return 0; } int startWinsock() { WSADATA wsa; return WSAStartup(MAKEWORD(2,0),&wsa); }
CLIENT:
#include <windows.h> #include <cstdio> #include <conio.h> using namespace std; //Prototypen int startWinsock(); int main() { SOCKET s; SOCKADDR_IN addr; int rc; char buf[256]; rc=startWinsock(); if(rc!=0) { printf("Fehler: startWinsock, fehler code: %d\n",rc); return 1; } else { printf("Winsock gestartet!\n"); } s=socket(AF_INET,SOCK_STREAM,0); if(s==INVALID_SOCKET) { printf("Fehler: Der Socket konnte nicht erstellt werden, fehler code: %d\n",WSAGetLastError()); return 1; } else { printf("Socket erstellt!\n"); } memset(&addr,0,sizeof(SOCKADDR_IN)); // zuerst alles auf 0 setzten addr.sin_family=AF_INET; addr.sin_port=htons(12345); // wir verwenden mal port 12345 addr.sin_addr.s_addr=inet_addr("127.0.0.1"); // zielrechner ist unser eigener rc=connect(s,(SOCKADDR*)&addr,sizeof(SOCKADDR)); if(rc==SOCKET_ERROR) { printf("Fehler: connect gescheitert, fehler code: %d\n",WSAGetLastError()); getchar(); return 1; } else { printf("Verbunden mit 127.0.0.1..\n"); } // HIER WEITERMACHEN!! strcpy(buf,"Hallo wie gehts?"); rc=send(s,buf,9,0); getchar(); return 0; } int startWinsock() { WSADATA wsa; return WSAStartup(MAKEWORD(2,0),&wsa); }
Was mache ich falsch? (Mir ist klar dass da C Code mit C++ gemischt ist, aber mir gehts jetzt wirklich nur um die Datenübertragung)
-
Also ich würde dir empfehlen das in C++ zu machen.
Wenn du es in C machst, solltest du deine Strings terminieren.strcpy(buf,"Hallo wie gehts?\0");
Grüße
-
override schrieb:
Wenn du es in C machst, solltest du deine Strings terminieren.
strcpy(buf,"Hallo wie gehts?\0");
Kann mir eigtl nicht vorstellen, dass das in C notwendig wäre...
-
Initialisier den Puffer mal mit leerem Inhalt:
char buf[256] = "";
Bin mit ziemlich sicher, dass es mit der Terminierung zusammenhängt.
Ob ein \0 am Ende ist, sollte in C++ oder C eigtl. keinen Unterschied machen, du brauchst auf jedenfall eine Terminierung.
-
Es ist immer dasselbe...
recv(..) kehrt nicht unbedingt dann zurück, wenn dein String vollständig übertragen ist, sondern auch mehrmals... Du musst berücksichtigen, dass z.B. zerst 5 Bytes, dann 7 Bytes übertragen werden...Simon
-
Cypog schrieb:
Bin mit ziemlich sicher, dass es mit der Terminierung zusammenhängt.
Ob ein \0 am Ende ist, sollte in C++ oder C eigtl. keinen Unterschied machen, du brauchst auf jedenfall eine Terminierung.Sag mal... wiedersprichst du dir selbst oder bin ich zu blöd zum Lesen?
-
override schrieb:
Cypog schrieb:
Bin mit ziemlich sicher, dass es mit der Terminierung zusammenhängt.
Ob ein \0 am Ende ist, sollte in C++ oder C eigtl. keinen Unterschied machen, du brauchst auf jedenfall eine Terminierung.Sag mal... wiedersprichst du dir selbst oder bin ich zu blöd zum Lesen?
er widerspricht sich... außerdem ist auch das hier falsch:
[qute="Cypog"]
Initialisier den Puffer mal mit leerem Inhalt:char buf[256] = "";
[/quote]
wenn überhaupt, dannchar buf[256] = { 0 };
aber ansonsten is natürlich das, was theta gesagt hat, der punkt ^^
bb
-
Wieso widerspreche ich mir? Lest mal genau!
Was ist bitte der Unterschied:
char str[256] = "";
oder
char str[256] = {0};
sollte beides den selben Effekt haben.
Verbessert mich, wenn ich mich irre.Auf jedenfall ist es seltsam:
strcpy(buf,"Hallo wie gehts?"); rc=send(s,buf,9,0);
Wieso 9?
-
1. hab ich genau gelesen - du hast es einfach falsch geschrieben...
2. gehört das, was du jz fragst zu den grundlagen...
= {0}
: _alle_ Elemente mit 0 initialisieren= ""
: _erstes_ Element mit '\0' (= 0) initialisieren
und da das erste element eh wieder überschrieben wird (wenn nix schief geht ^^), kannste so was auch gleich weglassen...bb
-
"blablabla\0"
Ist Käse. In C und C++ haben String Literale automatisch eine 0 Terminierung.unskilled schrieb:
gehört das, was du jz fragst zu den grundlagen...
= {0}
: _alle_ Elemente mit 0 initialisieren= ""
: _erstes_ Element mit '\0' (= 0) initialisieren
und da das erste element eh wieder überschrieben wird (wenn nix schief geht ^^), kannste so was auch gleich weglassen...Du solltest mal deine Grundlagen auffrischen.
""
ist genauso ein Intializer bei char Arrays wie{ 0 }
. Alle übrigen Elemente werden mit dem Default-Value-Intializer initialisiert. Ein Unterschied gibt es hier somit nicht.Grüssli
-
Dann sag nicht üöä falsch, sondern sag mir, was an der Aussage falsch ist!
Auf jedenfall, weiß ich nicht, was du willst,
char bla[10] = "";
und char bla[10] = {0};
hat bei mir den selben Effekt.
-
unskilled schrieb:
gehört das, was du jz fragst zu den grundlagen...
= {0}
: _alle_ Elemente mit 0 initialisieren= ""
: _erstes_ Element mit '\0' (= 0) initialisieren
und da das erste element eh wieder überschrieben wird (wenn nix schief geht ^^), kannste so was auch gleich weglassen...Du solltest mal deine Grundlagen auffrischen.
""
ist genauso ein Intializer bei char Arrays wie{ 0 }
. Alle übrigen Elemente werden mit dem Default-Value-Intializer initialisiert. Ein Unterschied gibt es hier somit nicht.[/quote]humm.. is mir neu - im standard hab ich jz zwar net geschaut aber mein treuer gefährte, der msvc gibt dir auf jeden fall recht
sry ^^
-
Run-Time Check Failure #3 - The variable 's' is being used without being initialized.
Visual C++ 2008 gibt mir diese Meldung aus, wenn ich Client & Server starte...
Cypog schrieb:
strcpy(buf,"Hallo wie gehts?"); rc=send(s,buf,9,0);
Wieso 9?
Ich wollte nur testen. Ich weiß, dass dann nur "Hallo wie" übertragen wird.
theta schrieb:
Es ist immer dasselbe...
recv(..) kehrt nicht unbedingt dann zurück, wenn dein String vollständig übertragen ist, sondern auch mehrmals... Du musst berücksichtigen, dass z.B. zerst 5 Bytes, dann 7 Bytes übertragen werden...Simon
Okay ^^. Und wie kriege ich das jetzt zum Laufen? Wenn ich den String terminiere, sendet er gar nichts...
-
skullyan schrieb:
Visual C++ 2008 gibt mir diese Meldung aus, wenn ich Client & Server starte...
Was ja auch stimmt. Du verwendest die Variable
s
ohne sie jemals initialisiert zu haben. Du verwendest als SocketacceptSocket
undconnectedSocket
, abers
wird nirgends initialisiert. Das muss scheitern ...Grüssli
PS: Irgendjemand hat den Thread gekillt ... zumindest bei mir ist die Formatierung futsch ...
-
Forum-Bug?!
scho ma versucht, die Fehlermeldung zu lesen?
und noch wichtiger: scho ma versucht, den Quellcode, den du vor dir hast, zu verstehen?
ich würd außerdem ma behaupten wollen, dass du was geändert hast, nachdem du ihn runtergeladen hast - und die Änderung war sicherlich falsch
Aber ich bin ma nich so:
-> s ist nicht initialisiert ^^ wahrscheinlich verstehst du das mit dem fkt aufrufen nich ganz und hast dir deshalb extra noch nen SOCKET erstellt, der s heißt, der Aufruf sollte aber vrmtl mitconnectedSocket
statts
geschehen...
-> kann jmd den Thread evtl ma ins WinAPI-Forum verschieben?!bb
-
Dieser Thread wurde von Moderator/in volkard aus dem Forum C++ in das Forum WinAPI verschoben.
Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?Dieses Posting wurde automatisch erzeugt.
-
unskilled schrieb:
Forum-Bug?!
scho ma versucht, die Fehlermeldung zu lesen?
und noch wichtiger: scho ma versucht, den Quellcode, den du vor dir hast, zu verstehen?
ich würd außerdem ma behaupten wollen, dass du was geändert hast, nachdem du ihn runtergeladen hast - und die Änderung war sicherlich falsch
Aber ich bin ma nich so:
-> s ist nicht initialisiert ^^ wahrscheinlich verstehst du das mit dem fkt aufrufen nich ganz und hast dir deshalb extra noch nen SOCKET erstellt, der s heißt, der Aufruf sollte aber vrmtl mitconnectedSocket
statts
geschehen...
-> kann jmd den Thread evtl ma ins WinAPI-Forum verschieben?!bb
JAAA!! Das war es, danke!!