Dateien über Winsock versenden
-
Wozu so umständlich? Wenn du die Dateigröße direkt als int am Anfang überträgst sind das doch immer 4 Bytes

-
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