Client/Server-App mit Sockets...
-
Ich beschäftige mich gerade auch damit, wie man am besten große Datenmengen transportieren kann. Zum Transport von Dateien würde ich das FTP-Protokoll vorschlagen. Auf IP-Ebene gibt es die Möglichkeit, den Stack aufzufordern, mit der größtmöglichen MTU zu arbeiten. Dazu benutzt man wohl das Hilfsprotokoll PMTUD (Path MTU Discovery), indem man das DF-Flag (Don't Fragment) setzt.
Wie das aber geht, habe ich noch nicht rausgefunden.
-
Es sit nicht gerade förderlcih die Packte über 1024 zu vergrößern, denn das ist die größe womit ethernet besonder gut arbeiten kann.....
Und was das TCP/IP Protokoll macht, macht es schon lange udn daher halte ich es persönlich gesehen für nicht sinnvoll da zu versuchen da mitzumischen, denn es garantiert einen Grund warum es alles so nutzen wie es ist....(Außer leuten, denen es Spass macht, andere mit nicht korrekten Packeten zu bombardieren)
-
Nox schrieb:
Es sit nicht gerade förderlcih die Packte über 1024 zu vergrößern, denn das ist die größe womit ethernet besonder gut arbeiten kann.....
Und was das TCP/IP Protokoll macht, macht es schon lange udn daher halte ich es persönlich gesehen für nicht sinnvoll da zu versuchen da mitzumischen, denn es garantiert einen Grund warum es alles so nutzen wie es ist....(Außer leuten, denen es Spass macht, andere mit nicht korrekten Packeten zu bombardieren)vielleicht kennst du mirc...warum kann man da die packetgröße von 1024 bis glaube ich 4096 einstellen? ich dachte auch eher an tcp/ip, so wie es halt icq macht!?
cu
-
Nox schrieb:
Es sit nicht gerade förderlcih die Packte über 1024 zu vergrößern, denn das ist die größe womit ethernet besonder gut arbeiten kann.....
Und was das TCP/IP Protokoll macht, macht es schon lange udn daher halte ich es persönlich gesehen für nicht sinnvoll da zu versuchen da mitzumischen, denn es garantiert einen Grund warum es alles so nutzen wie es ist....(Außer leuten, denen es Spass macht, andere mit nicht korrekten Packeten zu bombardieren)Da habe ich aber was anderes gelesen:
Durch die Fragmentierung wird der Verwaltungsaufwand größer, weil mehr Header erforderlich sind und die Reassemblierung durchgeführt werden muss.Von daher wäre es besser, mit der größtmöglichen MTU zu arbeiten. Da die Pakete aber oft über mehrere Teilstrecken mit unterschiedlichen MTUs geführt werden, ist diese nicht unmittelbar feststellbar. Moderne IP-Implementierungen benutzen dazu das Hilfsprotokoll PMTUD (Path MTU Discovery), indem sie das DF-Flag (Don't Fragment, Bit 17) setzen. Sie beginnen mit großen MTU-Werten und erhalten die Fehlermeldung "Fragmentierung notwendig" über das ICMP-Protokoll, dann vermindern sie so lange den MTU-Wert, bis die Fehlermeldungen ausbleiben.
Frage ist nur, ob man überhaupt Einfluss darauf hat, ob es also die Möglichkeit gibt, dies Einstellungen zu ändern.
-
Also ich habe mal vorn nem jahr da nen testbericht gesehen,der eindeutig zeigte das 1024 das beste war.....(ich kenne die config des testsystems aber nicht)
-
#include <winsock2.h> #include <windows.h> #include <stdio.h> #include <conio.h> #include <iostream.h> #include <string.h> #pragma comment( lib, "ws2_32.lib" ) typedef struct _NETFILEHEADER { unsigned long FileSize; char pFileName[256]; } NETFILEHEADER; long SendFileToNet(const char *pFileName, const char *pIP, unsigned short Port) { FILE *pFile; unsigned long FileSize; char buffer[1024]; NETFILEHEADER FileHeader; SOCKET sender; WSADATA wsa; SOCKADDR_IN addr; int addrlen = sizeof(SOCKADDR_IN); pFile = fopen(pFileName, "rb"); if(!pFile) return 0; fseek(pFile, 0, SEEK_END); FileSize = ftell(pFile); fseek(pFile, 0, SEEK_SET); FileHeader.FileSize = FileSize; memset(FileHeader.pFileName, 0, 256); memcpy(FileHeader.pFileName, pFileName, strlen(pFileName)); WSAStartup(MAKEWORD(2,0),&wsa); sender = socket(AF_INET, SOCK_STREAM, 0); memset(&addr, 0, sizeof(SOCKADDR_IN)); addr.sin_family = AF_INET; addr.sin_port = htons(Port); addr.sin_addr.s_addr = inet_addr(pIP); connect(sender, (SOCKADDR*)&addr, addrlen); send(sender, (char*)&FileHeader, sizeof(NETFILEHEADER), 0); while(FileSize >= 1024) { fread(buffer, 1024, 1, pFile); send(sender, buffer, 1024, 0); FileSize -= 1024; } if(FileSize) { fread(buffer, FileSize, 0, pFile); send(sender, buffer, FileSize, 0); } closesocket(sender); fclose(pFile); WSACleanup(); return FileSize; } long GetFileFromNet(unsigned short Port) { SOCKET server; SOCKET client; WSADATA wsa; SOCKADDR_IN addr; char buffer[1024]; long rval; FILE *pFile; NETFILEHEADER FileHeader; long FileSize; int addrlen = sizeof(SOCKADDR_IN); WSAStartup(MAKEWORD(2,0),&wsa); server = socket(AF_INET, SOCK_STREAM, 0); memset(&addr, 0, sizeof(SOCKADDR_IN)); addr.sin_family = AF_INET; addr.sin_port = htons(Port); addr.sin_addr.s_addr = INADDR_ANY; bind(server, (SOCKADDR*)&addr, sizeof(SOCKADDR_IN)); listen(server, 10); client = accept(server, (SOCKADDR*)&addr, &addrlen); //recv(client, (char*)&FileHeader, sizeof(NETFILEHEADER), 0); char *FileHeader1 = new(char[sizeof(Netfileheader)]; unsigned long AlreadyReceived = 0 unsigned long rc = 0; char* p = Fileheader1; do { rc = recv(client, p, sizeof(NETFILEHEADER)-AlreadyReceived, 0); AlreadyReceived += rc; p += rc; }while(AlreadyReceived<sizeof(NETFILEHEADER)); memcopy(FileHeader1, Netfileheader, sizeof(NETFILEHEADER)); FileSize = FileHeader.FileSize; pFile = fopen(FileHeader.pFileName, "wb"); while(FileSize > 0) { rval = recv(client, buffer, 1024, 0); fwrite(buffer, rval, 1, pFile); FileSize -= rval; } fclose(pFile); closesocket(client); closesocket(server); WSACleanup(); return FileHeader.FileSize; } void main(void) { // server: SendFileToNet("net.cpp", "192.168.0.1", 80); // client: GetFileFromNet(80); }hi, hab da das mal mit 1024 probiert! würde ja so passen????
bitte um tipps!cu
-
also ich würde es so machen:
// zuerst den Dateiinhalt auslesen int bytesRead = 0; int bytesTotalRead = FileSize; do { bytesRead = fread(buffer, 1024, 1, pFile); bytesTotalRead -= bytesRead; } while (bytesTotalRead != 0); // senden send(sender, buffer, FileSize, 0);Bei TCP muss du die Pakete nicht selber zerlegen, das macht TCP von alleine.
-
proga schrieb:
also ich würde es so machen:
// zuerst den Dateiinhalt auslesen int bytesRead = 0; int bytesTotalRead = FileSize; do { bytesRead = fread(buffer, 1024, 1, pFile); bytesTotalRead -= bytesRead; } while (bytesTotalRead != 0); // senden send(sender, buffer, FileSize, 0);Bei TCP muss du die Pakete nicht selber zerlegen, das macht TCP von alleine.
ja was ist aber wenn die datei sagn wir 531 kbyte groß ist? da kannst ja wohl kaum immer 1024 nehmen!!!! ja was ist wenn du eine 20MB datei senden willst? dann das mit einem sende() senden ist ja auch net ok?
cu
-
Also er verpackt das nochmal und wenn es ihm von der länge nicht passt sucht er sich selbst was aus. Da kann man halt nciht sicher sein, ob es 100% ist....
-
#include <winsock2.h> #include <windows.h> #include <stdio.h> #include <conio.h> #include <iostream.h> #include <string.h> #pragma comment( lib, "ws2_32.lib" ) typedef struct NETFILEHEADER { unsigned long FileSize; char pFileName[256]; }; long SendFileToNet(const char *pFileName, const char *pIP, unsigned short Port) { unsigned long FileSize; char buffer[1024]; NETFILEHEADER FileHeader; SOCKET sender; WSADATA wsa; SOCKADDR_IN addr; int addrlen = sizeof(SOCKADDR_IN); ////////////// Datei zum Lesen öffnen ////////////////////////// ifstream datei(pFileName, ios::binary); if (!datei) /* Fehler */ return 0; ////////////// Dateigrösse bestimmen /////////////////////////// in_file.seekg (0, ios::end); FileSize = in_file.tellg(); in_file.seekg (0, ios::beg); /////////////// NETFILEHEADER initialisieren /////////////////// FileHeader.FileSize = FileSize; memset(FileHeader.pFileName, 0, 256); memcpy(FileHeader.pFileName, pFileName, strlen(pFileName)); ////////////// Winsock initialisieren ////////////////////////// WSAStartup(MAKEWORD(2,0),&wsa); sender = socket(AF_INET, SOCK_STREAM, 0); memset(&addr, 0, sizeof(SOCKADDR_IN)); addr.sin_family = AF_INET; addr.sin_port = htons(Port); addr.sin_addr.s_addr = inet_addr(pIP); connect(sender, (SOCKADDR*)&addr, addrlen); /////////////////// NETFILEHEADER senden //////////////////////// send(sender, (char*)&FileHeader, sizeof(NETFILEHEADER), 0); /////////////////// Datei senden //////////////////////////////// while(FileSize >= 1024) { in_file.read(buf, 1024); send(sock, buf, stream.gcount(), 0); FileSize -= 1024; } if(FileSize) { in_file.read(buffer, FileSize); send(sock, buffer, stream.gcount(), 0); } /////////////////// Winsock schließen ////////////////////////// closesocket(sender); datei.close(); WSACleanup(); return FileSize; } long GetFileFromNet(unsigned short Port) { SOCKET server; SOCKET client; WSADATA wsa; SOCKADDR_IN addr; char buffer[1024]; long rval; FILE *pFile; NETFILEHEADER FileHeader; long FileSize; ////////////// Winsock initialisieren ////////////////////////// int addrlen = sizeof(SOCKADDR_IN); WSAStartup(MAKEWORD(2,0),&wsa); server = socket(AF_INET, SOCK_STREAM, 0); memset(&addr, 0, sizeof(SOCKADDR_IN)); addr.sin_family = AF_INET; addr.sin_port = htons(Port); addr.sin_addr.s_addr = INADDR_ANY; bind(server, (SOCKADDR*)&addr, sizeof(SOCKADDR_IN)); listen(server, 10); client = accept(server, (SOCKADDR*)&addr, &addrlen); /////////////////// NETFILEHEADER empfangen ///////////////////// char *FileHeader1 = new(char[sizeof(Netfileheader)]; unsigned long AlreadyReceived = 0 unsigned long rc = 0; char* p = Fileheader1; do { rc = recv(client, p, sizeof(NETFILEHEADER)-AlreadyReceived, 0); AlreadyReceived += rc; p += rc; }while(AlreadyReceived<sizeof(NETFILEHEADER)); memcopy(FileHeader1, Netfileheader, sizeof(NETFILEHEADER)); FileSize = FileHeader.FileSize; /////////////////// Datei empfangen ///////////////////////////// ofstream datei(FileHeader.pFileName,ofstream::binary); // In Datei schreiben while(FileSize > 0) { rval = recv(client, buffer, 1024, 0); out_file.write(buf,sizeof(buf)); FileSize -= rc; } /////////////////// Winsock schließen ////////////////////////// datei.close(); closesocket(client); closesocket(server); WSACleanup(); return FileHeader.FileSize; } void main(void) { // server: SendFileToNet("net.cpp", "192.168.0.1", 80); // client: GetFileFromNet(80); }hi, ich hab da mal streams eingebaut!
kann man für den char Buffer auch std::string nehmen fürs send:
send(sock, buf.c_str(), stream.gcount(), 0);funzt das:
ifstream datei(pFileName, ios::binary);verlagt da der 1 param. const char *FileName ??? will da auch lieber std::string nehmen...
beim emfangen des NETFILEHEADER, wie könnte man das besser machen?
cu