Char Buffer Problem



  • Hey.

    ich wollte mir ne kleine TCP Func schreiben, aber ich bleibe schon daran hängen dein Packet zu erstellen.

    Ich übergebe der Funktion einen Pointer zu nem Buffer, wo das Packet reingeschieben wird.

    Um zu überprüfen ob auch alles Passt hab ich mir dieses einfach mal in ne Datei schreiben lassen. Den Buffer hab ich recht großzügig gestalltet, da, wenn mal Cookies dabei sind, das gane recht groß werden kann.

    Aber egal. Ich lass das Packet also in ne Datei schreiben, und alle mit zeichen besetzten Elemente des Char Arrays passen soweit, aber alles was darüber raus läuft, da kommt was komisches dabei raus.

    Also hier mal mein Quellcode :

    #include <winsock2.h>
    #include <ws2tcpip.h>
    #include <windows.h>
    #include <stdio.h>
    #include <tchar.h>
    #pragma comment(lib, "wininet.lib")
    #pragma comment(lib, "Ws2_32.lib")
    
    int TCPSendRecv (int Type, char *Host, char *Page, char *Referer, char *Cookie) ;
    void SetPacket(int Type, char *Host, char *Page, char *Referer, char *Cookie, char *PacketBuf) ;
    LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
    
    int JustaTest (HWND hwnd)
    {
    	/*
    	int iResult ; 
    	WSADATA wsaData;
        iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
        if (iResult != NO_ERROR) {
            //wprintf(L"WSAStartup failed with error: %d\n", iResult);
    		return 0;
        }
    	*/
    	char buf[500] ;
    	HANDLE hFile ;
    	DWORD Written;
    
    	SetPacket(1, "www.google.de", "\\", "", "", buf) ;	
    	hFile = CreateFile(L"C:\\Test.txt", GENERIC_READ|GENERIC_WRITE,FILE_SHARE_WRITE|FILE_SHARE_READ,NULL,CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL) ;
    	WriteFile(hFile, buf, strlen(buf) + 1, &Written, 0) ;
    	CloseHandle (hFile) ;
    
    	return 0 ;
    }
    
    int TCPSendRecv (int Type, char *Host, char *Page, char *Referer, char *Cookie)
    {
    	char	Ret[4] ;
    	char	sendBuf[500] ;
    	char	RecBuf[500] ;
    	int		iResult ;
    	SOCKET	s ;
    	struct	sockaddr_in Server ; 
    
    	SetPacket(Type, Host, Page, Referer, Cookie, sendBuf) ;
    
    	// Init an Socket
    	s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) ;
    
    	// Set the Server Infos (muss mir noch klarwerden, wie das alles funktioniert !)
        Server.sin_family = AF_INET ;
        Server.sin_addr.s_addr = inet_addr (Host) ;
        Server.sin_port = htons (80) ;
    
    	// Connect to Server
    	iResult = connect (s, (SOCKADDR*) &Server, sizeof(Server)) ;
        if (iResult != 0) {
            WSACleanup ();
            return 0;
        }
    
    	// Send to Server
    	iResult = send (s, sendBuf, (int)strlen(sendBuf), 0) ;
        if (iResult != 0) {
            WSACleanup ();
            return 0;
        }
    
    	// Close the Connection to the Server
        iResult = closesocket(s);
        if (iResult != 0) {
            WSACleanup ();
            return 0;
        }
    	return 1 ;
    }
    
    void SetPacket(int Type, char *Host, char *Page, char *Referer, char *Cookie, char *PacketBuf)
    {
    	char buf[500] ;	
    	int i, u ;
    	switch (Type)
    	{
    	case 1 :		
    		sprintf (buf, "GET %s HTTP/1.1 \r\n"
    						  "Host: %s \r\n"
    						  "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; de; rv:1.9.2.4) Gecko/20100611 AskTbUT2V5/3.8.0.12304 Firefox/3.6.4 \r\n"
    						  "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 \r\n"
    						  "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 \r\n"
    						  "Keep-Alive: 115 \r\n"
    						  "Connection: keep-alive \r\n",
    						  Page,
    						  Host) ;
    		if (strlen (Referer) > 1)
    			sprintf (buf, "%s \r\n"
    						  "Referer: %s \r\n",
    						   buf,
    						   Referer) ;
    		if (strlen (Cookie) > 1)
    			sprintf (buf, "%s \r\n"
    						  "Cookie: %s \r\n",
    						  buf,
    						  Cookie) ;
    		// Abschließendes @crlf anhängen
    		sprintf (buf, "%s \r\n", buf) ;
    
    	}
    	u = strlen (buf) ;
    	for (i = 0 ; i < u ; i++)
    	{
    		PacketBuf[i] = buf[i] ;
    	}
    
    }
    
    int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
    {			
    	static TCHAR szAppName[] = TEXT ("Mein Standard Window") ;
    	HWND		hwnd ;
    	MSG			msg ;
    	WNDCLASS	wndclass ;
    	HBRUSH		hbrush = CreateSolidBrush(RGB(200,200,200)) ; 
    
    	wndclass.style			= CS_HREDRAW | CS_VREDRAW ;
    	wndclass.lpfnWndProc	= WndProc ;
    	wndclass.cbClsExtra		= 0 ;
    	wndclass.cbWndExtra		= 0 ;
    	wndclass.hInstance		= hInstance ;
    	wndclass.hIcon			= LoadIcon (NULL, IDI_APPLICATION) ;
    	wndclass.hCursor		= LoadCursor (NULL, IDC_ARROW) ;
    	wndclass.hbrBackground	= hbrush ;
    	wndclass.lpszMenuName	= NULL ;
    	wndclass.lpszClassName	= szAppName ;
    
    	if (!RegisterClass (&wndclass))
    	{	// Unicode Compilierung kann nur ein fehler sein !
    		MessageBox (NULL, TEXT("Fehler"), szAppName, MB_ICONERROR) ;
    		return 0 ;
    	}
    
    	hwnd = CreateWindow (szAppName,													//Name der Fensterklasse
    						szAppName,													//Fenstertitel
    						WS_OVERLAPPEDWINDOW,										//Styles
    						CW_USEDEFAULT,												//X-Pos
    						CW_USEDEFAULT,												//Y-Pos
    						CW_USEDEFAULT,												//Breite
    						CW_USEDEFAULT,												//Höhe
    						NULL,														//Parent Fenster
    						NULL,														//Menü
    						hInstance,													//Programm-Kopiezähler
    						NULL) ;														//Sonstige Parameter
    
    	ShowWindow (hwnd, iCmdShow) ;
    	UpdateWindow (hwnd) ;
    
    	while (TRUE)
    	{
    		if (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
    		{
    			if (msg.message == WM_QUIT)
    				break ;
    			TranslateMessage (&msg) ;
    			DispatchMessage (&msg) ;
    		}
    		else
    		{			
    
    		}
    		Sleep(20) ;
    	};
    	return msg.wParam ;
    }
    
    LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {		
    	static int		cxChar, cyChar ;
    	static int		cxClient, cyClient ;	
    	static int		iStartButtonW, iStartButtonH ;	
    	static HWND		hButton ;
    	RECT			rect ;
    
    	switch (message)
    	{
    	case WM_CREATE :		
    		// Get Char width and height
    		cxChar = LOWORD (GetDialogBaseUnits()) ;
    		cyChar = HIWORD (GetDialogBaseUnits()) ;
    
    		iStartButtonW = 20 * cxChar ;
    		iStartButtonH = 7 * cyChar / 4 ;
    
    		GetClientRect (hwnd, &rect) ;	
    
    		hButton = CreateWindow ( TEXT ("Button"),							// Classenname
    								TEXT ("Do it"),								// Beschriftung
    								WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON,	// Style
    								(rect.right / 2) - (iStartButtonW / 2),		// xPos
    								(rect.bottom / 2) - (iStartButtonH / 2),	// yPos
    								iStartButtonW,								// Breite
    								iStartButtonH,								// Höhe
    								hwnd,										// Parent
    								(HMENU) 1,									// Ist hier die ID, hat nichts mit einem Menü zu tun !
    								((LPCREATESTRUCT) lParam) -> hInstance, NULL ) ;					
    
    		return 0 ;
    
    	case WM_PAINT :
    
    		return 0 ;		
    
    	case WM_SIZE :
    		GetClientRect (hwnd, &rect) ;	
    		MoveWindow(hButton, (rect.right / 2) - (iStartButtonW / 2), (rect.bottom / 2) - (iStartButtonH / 2), iStartButtonW, iStartButtonH, FALSE) ;	
    		return 0 ;
    
    	case WM_COMMAND :		
    		switch (wParam)
    		{
    		case 1 :			
    			JustaTest (hwnd) ;
    			break ;
    		}
    		return 0 ;
    
    	case WM_DESTROY :
    		PostQuitMessage (0) ;
    		return 0 ;
    
    	}
    	return DefWindowProc (hwnd, message, wParam, lParam) ;
    }
    

    Und hier die datei die erstellt wird :

    GET www.google.de HTTP/1.1 
    Host: \ 
    User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; de; rv:1.9.2.4) Gecko/20100611 AskTbUT2V5/3.8.0.12304 Firefox/3.6.4 
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 
    Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 
    Keep-Alive: 115 
    Connection: keep-alive 
    
    ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌæ‚ÑÕÔò
    

    Warum ist das so, und gibt es ne bessere Lösung ?



  • for (i = 0 ; i < u ; i++) 
        { 
            PacketBuf[i] = buf[i] ; 
        }
    

    Bei dieser Kopierschleife hast du vergessen, den Null-Terminator deines Puffers zu übernehmen, deshalb lesen alle nachfolgenden Funktionen den Datenmüll, der zufällig hinter deinem Array im Speicher liegt. Warum verwendest du nicht strcpy() dafür?
    PS: Du stellst nirgends sicher, daß du nicht über das Ende des verfügbaren Speichers hinausschreibst.



  • PacketBuf[i] am Schluss '\0' terminieren!
    Aber ich weis nicht ob da noch andere Sachen sind, habs nicht so genau angeschaut.

    EDIT:
    @CStoll Ich war wohl ein bisschen zu langsam 😉



  • Hey.

    Hmm ist ja schon fast peinlich xD
    Und warum ich strcpy nicht verwendet habe ?
    Das ist eig. ganz einfach, ich beschäfftige mich erst seit ~ 2 wochen intensiv mit c / c++ und der WinAPI, deshalb war mir diese Funktion einfach nciht bekannt, deshalb war für mich die einfachste Lösung ne for schleife in die einzelle elemene des Char Arrays zu kopieren.

    Das ich über die größe des buffers hinaus schießen kann, waar mir bekannt, jedoch hab ich es in dem bsp einfach vernachlässigt, da meine 2 arrays die selbe größe haben.



  • Darter schrieb:

    Das ich über die größe des buffers hinaus schießen kann, waar mir bekannt, jedoch hab ich es in dem bsp einfach vernachlässigt, da meine 2 arrays die selbe größe haben.

    Klar, beim Kopieren von buf nach PacketBuf hast du keine Probleme, die kommen schon vorher. Die sprinf()-Aufrufe, mit denen du den Request zusammenstellst, haben nämlich keine Ahnung, wieviel Platz sie nutzen dürfen - und nutzen deshalb soviel wie sie brauchen.

    Wenn du tatsächlich C++ zur Verfügung hast, solltest du übrigens auch dessen Möglichkeiten ausnutzen - die std::string ist um einiges sicherer als der Umgang mit char-Arrays.



  • CStoll schrieb:

    die std::string ist um einiges sicherer als der Umgang mit char-Arrays.

    Wobei ich hier nicht von "sicherer" sprechen würde.
    Wenn man weiss was man tut, sind die (STD) string Funktionen equ.



  • -lowbyte- schrieb:

    CStoll schrieb:

    die std::string ist um einiges sicherer als der Umgang mit char-Arrays.

    Wobei ich hier nicht von "sicherer" sprechen würde.

    Wie würdest du es denn nennen? Bei std::string mußt du dich auf jeden Fall nicht darum kümmern, wieviel Speicherplatz du anfordern mußt und ob du wirklich immer einen Null-Terminator ans Ende angehängt hat, da sie sich bereits um alles nötige kümmern.

    Wenn man weiss was man tut, sind die (STD) string Funktionen equ.

    Gibt es den Satz auch auf deutsch?



  • Warum?



  • lowbyte_ schrieb:

    Warum?

    Ja entschuldige! 🤡



  • -lowbyte- schrieb:

    lowbyte_ schrieb:

    Warum?

    Ja entschuldige! 🤡

    weil ich keine Ahnung habe, was du damit aussagen wolltest - vor allem das Wort "equ" sagt mir nicht sehr viel (Google nennt u.a. eine Liste mit Wörtern, die damit abgekürzt werden* und einen Staubsauger, Wikipedia leitet weiter zu einem Sternbild).

    * obwohl, die Bedeutung Extremely Qualified User könnte schon passen 😃


Anmelden zum Antworten