Dateien über Winsock versenden



  • Wirklich? Na, wenn das so ist 🙂
    - Aber mit welchen Funktionen (die nicht so kompliziert sind 🙄)
    kann ich denn dann meinen empangenen Buffer "auseinander nehmen"?



  • Du liest einfach das erste Byte aus (und wandelst es wieder in einen int um - anschließend setzt du den Pointer um einen Byte weiter 🙂



  • Schaue dir das mal an

    //receiver
    	while (ret != SOCKET_ERROR)
    	{
    		ret = recv (*connectedSocket, Buffer,(2*sizeof(int)),NULL);
    
    		if(ret == (2*sizeof(int)))
    		{
    			memcpy(&iCommandNr,Buffer,sizeof(int));
    			memcpy(&iRecBufferSize,&Buffer[sizeof(int)],sizeof(int));
    			cRecBuffer = new char[iRecBufferSize];
    
    			if(0 != iRecBufferSize)
    				recv (*connectedSocket, cRecBuffer,iRecBufferSize,NULL);
    
    			wsprintf(port,"%d",*connectedSocket);
    			iPos = m_This->m_listL.InsertItem(0,port);
    			m_This->SetLVMStructureL(iPos,1,cPlayerName);
    			m_This->SetFunctionName(iCommandNr,iPos);
    
    			m_This->cManagerServer.SendBuffer(iCommandNr,iRecBufferSize,cRecBuffer,&cSendBuffer,port);
    
    			delete [] cRecBuffer;
    			char * SendeBuffer;
    			char indicator = -1;
    			SendeBuffer = new char [((2*sizeof(int))+iRecBufferSize)+1];
    			memcpy(SendeBuffer,&iCommandNr,sizeof(int));
    			memcpy(&SendeBuffer[sizeof(int)],&iRecBufferSize,sizeof(int));
    			memcpy(&SendeBuffer[(2*sizeof(int))],cSendBuffer,iRecBufferSize);
    			memcpy(&SendeBuffer[(2*sizeof(int))+iRecBufferSize],&indicator,1);
    
    			send(*connectedSocket,SendeBuffer,(2*sizeof(int)), NULL);
    
    			int iSendData = 0;
    			int icount = 0;
    			int i = 0;
    			int ISize = iRecBufferSize+1;
    			bool bFirst = true;
    			do
    			{
    				if(1024 < (iRecBufferSize-icount))
    					iSendData = 1024;
    				else
    					iSendData = ISize-icount;
    				char szData = 1;
    				do
    				{
    					i = send(*connectedSocket,&SendeBuffer[(2*sizeof(int))+icount],iSendData, NULL);
    					ret = recv (*connectedSocket, Buffer,1,NULL);
    					if(ret != -1)
    						memcpy(&szData,Buffer,1);
    				}while(szData == 1 && ret != SOCKET_ERROR && ret != 0);
    
    				if(bFirst && i != 0)
    				{
    					bFirst = false;
    					icount--;
    				}
    				icount += i;
    				if(i == 0)
    					icount--;
    			}
    			while(icount != iRecBufferSize && ret != SOCKET_ERROR && ret != 0);
    			delete [] SendeBuffer;
    			delete [] cSendBuffer;
    			if(FSetClientName == iCommandNr)
    			{
    				CString ctmp;
    				ctmp = m_This->cManagerServer.GetClientName(port);
    				strcpy(cPlayerName,ctmp.GetBuff(ctmp.GetLength()));
    				ctmp.ReleaseBuffer();
    			}
    			continue;
    		}
    
    		if (ret == 0 || ret == SOCKET_ERROR)
    		{
    		}
    	}
    
    //Sender
    DLLEXPORT virtual void Send(int ifunctionNo,int &ISize,char *cSendBuffer,char **cRecBuffer)
    	{
    		char * TransmitBuffer;
    
    		TransmitBuffer = new char[(2*sizeof(int)+ISize)];
    
    		memcpy(TransmitBuffer,&ifunctionNo,sizeof(int));
    		memcpy(&TransmitBuffer[sizeof(int)],&ISize,sizeof(int));
    		memcpy(&TransmitBuffer[(2*sizeof(int))],cSendBuffer,ISize);
    
    		if(0 > send(ssocket, TransmitBuffer,((2*sizeof(int))+ISize),NULL))
    		{
    			bConnected = false;	
    		}
    		else
    		{
    			char sbuffer[8];
    
    			recv (ssocket,sbuffer,(2*sizeof(int)), NULL);
    
    			memcpy(&ifunctionNo,sbuffer,sizeof(int));
    			memcpy(&ISize,&sbuffer[sizeof(int)],sizeof(int));
    			ISize++;
    
    			if(0 < ISize)
    			{
    
    				*cRecBuffer = new char[ISize];
    				char indicator = -1;
    				char *ptemp ;
    				int i = 0;
    				int icount = 0;
    				int iReaddata = 0;
    				int iSendData = 0;
    				bool bFirst = true;
    
    				memset(*cRecBuffer,0,ISize);
    
    				char *tmp = new char [ISize];
    				do
    				{
    					indicator = -1;
    					if(1024 < (ISize-icount))
    						iReaddata = 1024;
    					else
    					{
    						if( 0 == icount)
    							iReaddata = ISize-icount;
    						else
    							iReaddata = ISize-icount;
    					}
    					char *crecievebuffer = new char[iReaddata];
    					memset(crecievebuffer,0,iReaddata);
    					i = recv(ssocket,crecievebuffer,iReaddata,NULL);
    					if(i == -1)
    					{
    						indicator = 1;
    						i = WSAGetLastError();
    						i = 0;
    					}
    					while(-1 == send(ssocket, &indicator,1,NULL));
    					memcpy(&tmp[icount],crecievebuffer,i);
    
    					if(bFirst && i != 0)
    					{
    						bFirst = false;
    						icount--;
    					}
    					icount +=i;
    					if(i == 0)
    						icount--;
    					ptemp = tmp;
    					delete [] crecievebuffer;
    
    				}while(ptemp[icount] != -1);
    				memcpy(*cRecBuffer,tmp,ISize);
    				delete [] tmp;
    			}
    		}
    		delete [] TransmitBuffer;
    	};
    

    So mache ich es in einem TCP Server von mir

    edit: sfds



  • Igitt!!! Wie wär's mal mit Code-Tags???



  • Sorry werde ab jetzt code-tags verwenden .
    Danke ichbins



  • OK - hab den Filetransfer jetzt doch mit der selbstgeschriebenen explode-Funktion geschafft. Allerding klappt das ganze nur bis zum 1. "|" Zeichen in der Gif-Datei. Da ja in so einer GIF-Datei alle möglichen Buchstaben und Zeichen vorkommen, weis ich leider net, welches Zeichen ich als Trennzeichen benutzen kann. 😕



  • Habe eine Lösung gefunden!
    Bin gerade dabei, eine while-Schleife zu programmieren, die überprüft, ob noch mehr Zeichen nach dem | kommen.

    (So in etwa):

    char * abort = "no"; int count = 2;
    while (abort == "no")
    {
    	String part[count] = explode('|', buf, count);
    	const char * cpart[count] = part[count].c_str();
    
    	if (strcmp(cpart[count], "") == 0) {abort = "yes";}
    	else {part1 + cpart[count]; count++;}
    }
    

    Natürlich ist der Code völlig falsch 🙄
    Aber wie kann man eigentlich Strings nach so einem Prinzip erstellen lassen?
    Ihr wisst hoffentlich, was ich meine 🙄



  • @ichbins17: hast du einen tcp server geproggt? kannst du mir eventuell mal die source geben: surfman19@gmx.at

    wär klass...
    cu



  • Hi @all!
    Habe es jetzt mit folgendem Code realisiert. Das Problem ist nur, dass keine Messagebox ausgegeben wird 😞

    int count = 3; char * abort = "no";
    			string part1 = explode('|', buf, 0);
    			string part2 = explode('|', buf, 1);
    			string part3;
    
    			const char * checkfile = part1.c_str();
    			const char * cfilesize = part2.c_str();
    
    			while (strcmp(abort, "no") == 0)
    			{
    				string apart = explode('|', buf, count);
    				const char * capart = apart.c_str();
    
    				if (strcmp(capart, "") != 0) {part3 + capart; count++;}
    				else {abort = "yes";}
    			}
    
    			const char * data = part3.c_str();
    			MessageBox(NULL, data, NULL, NULL);
    


  • deine messagebox weis nicht was sie tun soll (letzter parameter)
    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/windowing/dialogboxes/dialogboxreference/dialogboxfunctions/messagebox.asp

    so sollte es gehen

    MessageBox(NULL, part3.c_str(), "info", MB_OK);
    


  • Geht leider immer noch nicht 😞

    Zu meinem Code:
    Ich meinte natürlich

    if (strcmp(capart, "") != 0) {part3 + apart; count++;}
    


  • wenn du schon std::string benutz kannst du doch auch die einbauten funktionen benutzen siehe http://cplus.kompf.de/artikel/strings.html
    warum machst du abort nicht boolisch ?

    probiert es mal so
    [cpp]
    while (strcmp(abort, "no") == 0)
    {
    string apart = explode('|', buf, count);

    if(apart.compare("") != 0) // oder apart.size() > 0
    {
    part3 += apart;
    ++count;
    }
    else
    abort = "yes";

    }

    MessageBox(NULL, part3.c_str(), "info", MB_OK);
    [/cpp]



  • Geil! Es klappt endlich!
    Vielen Dank für die schnelle Antwort und den Codeschnipsel!
    Nach dem letzten Zeichen erscheint in der Messagebox zwar noch ein bisschen Müll - aber das bekomm´ ich bestimmt auch noch hin 😃 🙄

    THX Maxime

    Achja - bevor ich´s vergesse:
    VIELEN DANK AN ALLE, DIE AUF MEINE FRAGEN GEANTWORTET HABEN!
    IHR HABT MIR SEHR WEITERGEHOLFEN! 👍



  • 😡 ...Jaja... der Filetransfer klappt - aber leider nur bei kleinen Textdateien 😞 Bei Gif oder PNG-Dateien sieht das ganze dann in etwa so aus:

    ‰PNG
    
     ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍýýýýÝÝÝQ   ±   °œ P› ÀsB ¶   €         ýýýý @  @ `Q@ ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍýýýý    ±   1      Àœ $~B             ýýýýÿÿÿÿÁ
    ÍÍÿÿÿÿÁ
    ÍÍÿÿÿÿÁ
    ÍÍÿÿÿÿ
    

    😞
    Ich seh´ mich echt schon in ein paar Wochen mit ´nem FTP-Server hantieren 😞 😕



  • Hi!
    Ich könnte die Datei allerdings noch "binär" auslesen und sie in Einzelteilen versenden - aber ich habe
    noch keine Ahnung wie ich das anstellen soll 🙄

    crazychicken (alias "Maxime")

    PS:
    Kennt vielleicht jemand von euch ein gutes Tutorial über "Dateien über Winsock versenden"? Ich bin jetzt nämlich bei meinem Projekt so ziemlich mit meinem Latein am Ende 🙄



  • HANDLE fileHandle;
    DWORD fileSize;
    DWORD bytesRead;
    char *sendeBuffer;
    
    // Datei öffnen:
    fileHandle=CreateFile("test.gif",GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,0,NULL);
    
    // Dateigröße holen:
    fileSize=GetFileSize(fileHandle,NULL);
    
    // Speicher für die Datei und die Längenangabe holen:
    sendeBuffer=(char*)malloc( fileSize+sizeof(DWORD) );
    
    // Länge in den sendeBuffer kopieren:
    memcpy(sendeBuffer,(void*)&fileSize,sizeof(DWORD));
    
    // Datei hinter die Längenangabe in den sendeBuffer einlesen:
    ReadFile(fHandle,sendeBuffer+sizeof(DWORD),fileSize,&bytesRead,NULL);
    
    // DateiHandle schließen:
    CloseHandle(fileHandle);
    
    // Daten über Winsock senden:
    send(zielSocket,sendeBuffer,(fileSize+sizeof(DWORD)),0);
    
    // Speicher freigeben:
    free(sendeBuffer);
    

    So ungefähr würde ich das senden machen, also quasi erst senden wieviele Bytes kommen (einfach einen DWORD schicken) und direkt danach eben die komplette Datei binär rübersenden...



  • Vielen Dank für das Codebeispiel!
    Werde es (sobald ich Zeit habe) mal so ausprobieren.
    Vielleicht klappt´s ja dann 👍

    PS: Man könnte doch mal ein Beispiel der Dateiübertragung über Winsock in die FAQ´s stellen, oder? (Ist nur ein Vorschlag ;))

    crazychicken 🙂



  • Hi geeky!
    Habe dein Codebeispiel gleich´ mal in mein Projekt eingebunden und getestet:

    (Sender)

    HANDLE file;
    	char * buffer;
    	DWORD FileSize;
    	DWORD BytesRead;
    
    	file = CreateFile("test.txt", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
    	FileSize = GetFileSize(file, NULL);
    
    	buffer = (char*)malloc( FileSize+sizeof(DWORD) );
    	memcpy(buffer,(void*)&FileSize,sizeof(DWORD)); 
    
    	ReadFile(file, buffer+sizeof(DWORD), FileSize, &BytesRead, NULL);
    	CloseHandle(file);
    
    	send(connectedSocket, buffer, (FileSize+sizeof(DWORD)), 0);
    
    	free(buffer);
    

    Empfänger:

    char * check = "no"; char buf[40000]; 
    
    			while (check == "no")
    			{
    				rc=recv(s, buf, 40000, 0);
    				buf[rc]='\0';
    
    				if(strcmp(buf, "") != 0)
    				{check = "yes";}
    			}
    
    			MessageBox(NULL, buf, "info", MB_OK);
    

    test.txt - Datei:

    hidueihidueihidueihidueihidueihiduei
    hidueihidueihidueihidueihidueihiduei
    hidueihidueihidueihidueihidueihiduei
    hidueihidueihidueihidueihidueihiduei
    

    - doch leider werden nur NULL-Zeichen übertragen 😞
    Weis einer von euch, woran das liegen könnte?
    Der Code ist doch völlig richtig, oder nicht?

    Vielen Dank!
    carzychicken 🙂



  • (check == "no")

    Das kann schonmal nicht richtig sein. Stringvergleiche macht man mit lstrcmp



  • Danke!
    Hab es jetzt auf

    while (strcmp(check, "no") == 0)
    

    geändert - doch es werden von der Datei leider immer noch nur NULL-Zeichen übertragen.

    Wenn ich eine andere Datei zur Übertragung verwende, kommt der Dateicode komischerweise nur in Einzelteilen beim Server an.

    Ich versteh´ jetzt irgendwie gar nichts mehr... 🙄

    [EDIT]:
    Habe gerade mit einer MessageBox herausgefunden, dass die Datei gar nicht falsch empfangen, sondern schon falsch gesendet wird! 😮 Könnte vielleicht einer von euch nochmal über den Code gucken? Wäre euch dafür super dankbar!


Anmelden zum Antworten