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.aspso sollte es gehen
MessageBox(NULL, part3.c_str(), "info", MB_OK);
-
Geht leider immer noch nicht

Zu meinem Code:
Ich meinte natürlichif (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 aufwhile (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!