Frage zu WinSock2 und Sockets



  • Wie kann ich einen Socket leeren also mit einem Clear befehl(Ich meine nicht closeSocket)



  • Warum sollte man das wollen?



  • Du kannst den Socket auf non-Blocking schalten, und dann so lange recv() aufrufen bis du nen EWOULDBLOCK Fehler bekommst.
    Falls es das ist was du willst - also sicherstellen dass keine Daten mehr im Empfangspuffer stehen.

    Ansonsten beschreib besser was du willst. "Clear" Funktion kann je nach Kontext viel heissen - was du als "natürliche" Semantik für die Clear-Funktion eines Sockets annimmst können wir ja nicht wissen.



  • Ich meine das ich wenn ich ein socket erstelle beispiel: sListen(Empfang)
    will ich das wenn ich recv die daten vom client empfange das alle daten nicht an sListen angehängt werden sondern erst sListen geleert wird und dann die daten dort ungestört gespeichert werden kann



  • Ich verstehe deine Beschreibung nicht.
    Schreib das bitte nochmal mit verständlichem Satzbau und korrekter Grammatik, und vor allem mit dem üblichen Vokabular.



  • Ok also ich entwickle gerade ein File System mit einer Art Peer to Peer verbindung
    Aber ich will das wenn der der Sendet fertig ist, wird im Hintergrund eine nachricht gesendent, und beim Empfänger wird geprüft, in einer if abfrage ,ob das gesendete das wort ist, in meinem falle fertig ,dann soll er unterbrechen.Aber er nimmt noch die Daten vom Vorher gesendeten dazu somit wird die if nicht erfüllt, daher möchte ich den Socket leeren.



  • Sockets mit TCP sind Stream-basiert, d.h die Applikation muss wissen wann eine Meldung komplett ist (und auch wann noch nicht). D.h. du musst in deinem Programm erkennen wann das File komplett übertragen ist, und dann eine neue Meldung empfangen ("fertig"). Ev. hilft es wenn du deinen Empfangscode (oder Teile davon) hier zeigst.

    Ein bisschen Interpunktion und die Vermeidung von das/dass-Fehler sowie die Beachtung von Gross-und Kleinschreibung hilft dem Leser deines Posts ungemein. Damit wird dir schneller und reibungloser geholfen.



  • Boaaaaa...
    Wenn er so programmiert wie er Sätze zuammenbaut dann wird das nie was.



  • Vom Sender:

    res = bind(sListen,(struct sockaddr*)&info,infolen);
    		if(sListen != SOCKET_ERROR)
    		{
    			cout<<"Mit Server verbunden"<<endl;
    		}
    		else
    		{
    			cout<<"Server verbindung fehlgeschlagen:"<< WSAGetLastError <<endl;
    		}
    		res = listen(sListen,SOMAXCONN);
    		if(sListen != INVALID_SOCKET)
    		{
    			cout<<"Server bereit"<<endl;
    		}
    		else
    		{
    			cout<<"Server fehler:"<< WSAGetLastError <<endl;
    		}
    		sockaddr_in clientinfo;
    		int clientinfoles = sizeof(clientinfo);
    
    		sClient = accept(sListen,(struct sockaddr*)&clientinfo, &clientinfoles);
    		if(sClient != SOCKET_ERROR)
    		{
    			cout<<"Client accept: "<< inet_ntoa(clientinfo.sin_addr)<< ":"<< ntohs(clientinfo.sin_port) <<endl;
    
    		}
    
    		string datei;
    		string sende;
    		int i = 1;
    		cin >> sende;
    		ifstream open(sende,ios::in);
    		int size = sizeof(open);
    		while (!open.eof())
    		{
    			getline(open,datei);
    			if(i == 1)
    			{
    
    				cout<<"Sende"<<endl;
    			}
    
    			Sleep(5000);
    			res = send(sClient, datei.c_str(),strlen(datei.c_str()),0);
    			if(res == SOCKET_ERROR)
    			{
    				cout<<"Senden von Datei fehlgeschlagen"<<endl;
    			}
    			if(open.eof())
    			{
    
    				cout<<"Datei gesendet!"<<endl;
    			}
    			i = 2;
    		}
    		open.close();
    

    Vom Empfänger:

    res = connect(sListen,(struct sockaddr*)&info,infolen);
    		if(sListen != SOCKET_ERROR)
    		{
    			cout<<"Mit Server verbunden"<<endl;
    		}
    		else
    		{
    			cout<<"Server verbindung fehlgeschlagen:"<< WSAGetLastError <<endl;
    		}
    		res = listen(sListen,SOMAXCONN);
    		if(sListen != INVALID_SOCKET)
    		{
    			cout<<"Server bereit"<<endl;
    		}
    		else
    		{
    			cout<<"Server fehler:"<< WSAGetLastError <<endl;
    		}
    
    		char receive[1000];
    
    		int j = 1;
    		char datei[10];
    		res = recv(sListen,receive,sizeof(receive),0);
    		int sfor = sizeof(receive);
    		cout<< receive<<endl;
    		ofstream out("test.txt",ios::out);
    		while (1)
    		{
    			if(j == 1)
    			{
    				cout<<"Schleife 1"<<endl;
    			}
    
    			for(int i = 0;i<=sfor;i++)
    			{
    				res = recv(sListen, datei,sizeof(datei),0);
    				if(res == SOCKET_ERROR)
    				{
    					cout<<"Host has left!"<<endl;
    					Sleep(2000);
    					system("PAUSE");
    					system("cls");			
    					main();
    				}
    				j = 2;
    				out << datei;
    			}
    
    				cout<<"Datei uebertragen!"<<endl;
    				break;
    		}
    		out.close();
    


  • Folgender Post handelt dein Problem ungefähr ab. Dort wird zwar Boost.Asio verwendet, ist aber prinzipiell dasselbe. Um das umzusetzen musst du vorallem den Rückgabe-Wert von recv() benutzen, und zwar nicht bloss als Error-Code.
    http://www.c-plusplus.net/forum/285079

    Und hier noch eine Meldung betreffend Framing-Protokoll:
    http://www.c-plusplus.net/forum/p2103626#2103626



  • Hi,

    also alle Kreationisten und Künstler versteht man nicht gleich,
    weil kaum jemand so flexibel ist wie diese.

    Ich kenne aber deinen Ansatz, und das beste ist du schreibst eine Datenstruktur
    "raus" mit send() in dessen header Kopf steht immer die zu erwartende
    folgende Datenmenge. Beide Seiten kennen die Header länge.

    Transmitter:
    send(header)
    send(daten)

    Reciever:
    read(header)
    read(daten)

    Der Empänger ließt dann den Header, entnimmt die folgende Datenmenge als Zahlenwert und ließt diese direkt im Anschluß mit Receive. Wird dann die Länge nicht erreicht oder überschritten ist ein schwerer Fehler aufgetreten. Ich habe noch nie erlebt das die dann folgende Menge nicht aufs Byte passt. Mach es so.

    Ein Header hat noch andere Vorteile zb. Paketzähler Autentifizierung uvm.

    Bedenke auch das deine Pakete zerteilt werden, und nict immer im Stück
    ankommen müssen, das heißt für den Datenreceive in einer schleife lesen
    bis Länge erreicht oder Fehler.

    int CMySock::Receive(char *pMem,int Size)
    {
    	int iLen(0),cnt(0);
    
    	 while(((iLen += (cnt = recv(m_sock, (char *)(pMem+iLen), Size, 0))) < Size) && cnt > 0);
    
    	m_BytesReceive+=iLen;
    
    	return iLen;
    }
    

    Gruß K.


Log in to reply