Filetransfer via Winsock TCP Sockets... Klappt nicht einwansfrei!



  • Hallo! Naja mein Problem ist einfach auszudrücken. Ich rufe SendFile auf um über einen Socket eine Datei zu senden zu einem Clienten, der eine andere Funktion aufruft, die die Datei empfangen soll. Damals hatte ich es auf diesem Wege irgendwie hinbekommen, einwandfreier Datenverkehr, aber nun... Näheres gleich dazu... Schaut Euch erst mal die wichtigsten Codes an:
    (fopen zum öffnen der datei die gesendet/empfangen werden soll findet vorher wo anders statt!!!)...

    // SEND FUNKTION DES SERVERSvoid __cdecl SendFile(void *)
    {
    	char szMsg[MAX_PATH];
    	char szClientNo[MAX_PATH];
    
    	strcpy(szClientNo, szUsedNo);
    	sprintf(szMsg, "%s%s", szSendFrom, szSendFile);
    
    	SendMessage(GetDlgItem(hFile, IDC_PROGRESS), PBM_SETRANGE32, 0, lSendSize);
    	FILE* fFile2;
    	SendMessage(GetDlgItem(hFile, IDC_PROGRESS), PBM_SETPOS, (WPARAM)0, (LPARAM)0);
    	SetTimer(hFile, 0, 1000, NULL);
    	if((fFile2 = fopen(szMsg, "rb")) != 0)
    	{
    		char szBytesSent[MAX_PATH];
    		char szPercent[MAX_PATH];
    		char szBuffer[1024];
    		lBytesSent = 0;
    		int    iProzent = 0;
    		double dProzent = 0;
    		while(!feof(fFile2))
    		{
    			if(bFileTransfer)
    			{
    				long lBytesRead = fread(szBuffer, 1, sizeof(szBuffer), fFile2);
    				long lBytesCurrentSent = 0;
    				lBytesSent += lBytesRead;
    				if(lBytesRead > 0)
    				{
    					while(lBytesCurrentSent != lBytesRead)
    					{
    						long lNowSent = send(GetSocket2ByNo(szClientNo), szBuffer + lBytesCurrentSent, lBytesRead-lBytesCurrentSent, 0);
    						if(lNowSent == SOCKET_ERROR && WSAGetLastError() != WSAEWOULDBLOCK)
    						{
    							char szError[MAX_PATH];
    							sprintf(szError, "%i", WSAGetLastError());
    							MessageBox(NULL, szError, NULL, NULL);
    							_endthread();
    						}
    						lBytesCurrentSent += lNowSent;
    					}
    				}
    				sprintf(szBytesSent, "%i/%i", lBytesSent, lSendSize);
    				SetDlgItemText(hFile, IDC_INFO5, szBytesSent);
    				SendMessage(GetDlgItem(hFile, IDC_PROGRESS), PBM_SETPOS, (WPARAM)lBytesSent, (LPARAM)0l);
    				dProzent = dProzent + lBytesRead;
    				iProzent = dProzent / lSendSize * 100;
    				sprintf(szPercent, "%i%%", iProzent);
    				SetDlgItemText(hFile, IDC_INFO7, szPercent);
    			}
    			else
    			{
    				//WriteChatMessage("[PROGRAMM] Die Dateiübertragung wurde abgebrochen.", hTempDlg);
    				break;
    			}
    		}
    		fclose(fFile2);
    		if(bFileTransfer)
    		{
    			bFileTransfer = false;
    			SetDlgItemText(hFile, IDCANCEL,  "Schließen");
    			send(GetSocketByNo(szClientNo), "BFW_SENDDONE\n", strlen("BFW_SENDDONE\n"), 0);
    			sprintf(szMsg, "Filetransfer '%s%s' into '%s' successfully finished.", szSendFrom, szSendFile, szSendPath);
    			ListView_InsertItemEx(GetDlgItem(hControl, IDC_LIST2), NULL, NULL, NULL, NULL, NULL, szMsg, NULL, 2, -1);
    			SetDlgItemText(hFile, IDC_INFO6, "Done.");
    		}
    	}
    
    // RECEIVE FUNKTION DES CLIENTEN
    void __cdecl RecvFile(void *)
    {
    	char szRecvData[MAX_PATH];
    	long lReceived = 0;
    
    	while(lReceived != SOCKET_ERROR && bRunWhile)
    	{
    		lReceived = recv(sckSocket2, szRecvData, MAX_PATH, 0);
    		if(lReceived == -1)
    		{
    			char szMsg[MAX_PATH];
    			sprintf(szMsg, "WSALastError = %i\nlReceived = -1", WSAGetLastError());
    			MessageBox(NULL, szMsg, "röfl nen fehler", NULL);
    		}
    		else if(lReceived == 0)
    		{
    			char szMsg[MAX_PATH];
    			sprintf(szMsg, "WSALastError = %i\nlReceived = 0", WSAGetLastError());
    			MessageBox(NULL, szMsg, "röfl nen fehler", NULL);
    		}
    		else if(lReceived == SOCKET_ERROR)
    		{
    			char szMsg[MAX_PATH];
    			sprintf(szMsg, "WSALastError = %i\nlReceived = SOCKET_ERROR", WSAGetLastError());
    			MessageBox(NULL, szMsg, "röfl nen fehler", NULL);
    		}
    		else if(szRecvData != NULL)
    		{
    			szRecvData[lReceived] = '\0';
    			fwrite(szRecvData, 1, lReceived, fFile);
    		}
    	}
    	_endthread();
    }
    

    So nun solltet Ihr noch sehen, wie ich die Sockets erstelle:

    // BEIM CLIENTEN:
    char szMsg[MAX_PATH];
    
    	SOCKADDR_IN sockaddr_in;
    
    	closesocket(sckSocket2);
    
    	if((sckSocket2 = socket(AF_INET, SOCK_STREAM, 0)) != INVALID_SOCKET)
    	{
    		HOSTENT *host = gethostbyname(szIP);
    		memset(&sockaddr_in, 0, sizeof(SOCKADDR_IN));
    		sockaddr_in.sin_family      = AF_INET;
    		sockaddr_in.sin_port        = htons((u_short)atof(szPort));
    		sockaddr_in.sin_addr.s_addr = ((IN_ADDR*)host->h_addr)->s_addr;
    		if((connect(sckSocket2, (SOCKADDR *)&sockaddr_in, sizeof(SOCKADDR_IN))) != SOCKET_ERROR)
    		{
    			bRunWhile = true;
    			_beginthread(RecvFile, 0, NULL);
    		}
    	}
    	else MessageBox(NULL, "Socket create error.", NULL, NULL);
    
    // BEIM SERVER:
    
    closesocket(sckSocket2);
    	if((sckSocket2 = socket(AF_INET, SOCK_STREAM, 0)) != INVALID_SOCKET)
    	{
    		memset(&sockaddr_in, 0, sizeof(SOCKADDR_IN));
    		sockaddr_in.sin_family		= AF_INET;
    		sockaddr_in.sin_port		= htons((u_short)atof(szSPort2));
    		sockaddr_in.sin_addr.s_addr = (u_long) 0x00000000;
    		if(bind(sckSocket2, (SOCKADDR*)&sockaddr_in, sizeof(SOCKADDR_IN)) != SOCKET_ERROR)
    		 if(listen(sckSocket2, 10) != SOCKET_ERROR) WSAAsyncSelect(sckSocket2, hMainWnd, SOCKET_NOTIFY2, FD_ACCEPT);
    	}
    

    So. Wenn ich eine Datei sende, steht in meiner Statusanzeige im Programm ca. so ein Wert:

    Gesendet: 9411/23358233 Bytes. Also so z.B! Hmm naja und dann wird auch schon sofort

    if(lReceived == -1)
    {
    char szMsg[MAX_PATH];
    sprintf(szMsg, "WSALastError = %i\nlReceived = -1", WSAGetLastError());
    MessageBox(NULL, szMsg, "röfl nen fehler", NULL);
    }

    das heir aufgerufen! das heißt laut msdn:

    WSAECONNRESET
    10054
    Connection reset by peer.
    An existing connection was forcibly closed by the remote host. This normally results if the peer application on the remote host is suddenly stopped, the host is rebooted, the host or remote network interface is disabled, or the remote host uses a hard close (see setsockopt for more information on the SO_LINGER option on the remote socket). This error may also result if a connection was broken due to keep-alive activity detecting a failure while one or more operations are in progress. Operations that were in progress fail with WSAENETRESET. Subsequent operations fail with WSAECONNRESET.

    Ich verstehe die Welt nicht mehr!!! Seht Ihr einen Fehler???

    P.S.: Also was ich sicher weiß, eine Verbindung wird sauber hergestellt! Nur während der Übertragung, da geht was schief!!!

    DANKE! Chris



  • Hi!
    Ich hatte mal sowas ähnliches...
    Wenn du die Datei mit

    fopen("<datei>","r");
    

    öffnest funktioniert das nicht...

    Versuchs mal mit

    fopen("<datei>","rb+");
    

    dann müsste das funktionieren!

    Logischerweise musst du die Dateien dann auch wieder mit

    fopen("<datei>","wb+");
    

    zum schreiben öffnen!

    MfG.
    BlackViper



  • ...ich sehe gerade, dass du das bereits tust... 🙄
    sry



  • frag doch mal hier: http://www.win-api.com

    🙄



  • Wie groß ist die Datei und welche Meldungen gibt der Server aus?
    Für mich sieht es so aus, dass die der Server den socket wieder schließt, dann bekommt der Client diesen Fehler - evtl. also ein Fehler beim Server während des Lesens oder er ist damit fertig und killt die Verbindung.


Anmelden zum Antworten