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
