Wysyłanie pliku na serwer

0

Używam takiego kodu do wysyłania pliku ale nie pojawia się on na serwerze kod PHP jest na 100% prawidłowy ale problem występuje w C++ kod wygląda tak

 int upload(string arg1, string arg2) {
	WSADATA wsaData;

	if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
		return 1;
	}

	SOCKET Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

	struct hostent *host;
	host = gethostbyname("host");

	SOCKADDR_IN SockAddr;
	SockAddr.sin_port = htons(80);
	SockAddr.sin_family = AF_INET;
	SockAddr.sin_addr.s_addr = *((unsigned long*)host->h_addr);

	if(connect(Socket, (SOCKADDR*)(&SockAddr), sizeof(SockAddr)) != 0) {
		return 1;
	}

	char* header = (char*)("POST / HTTP/1.1\r\n"
					"Host: host\r\n"
					"Accept: text/html,aplication/xhtml+xml,application/xml;q=9,*/*;q=0.8\r\n"
      				        "Content-Type: multipart/form-data; boundary=upload\r\n"
      				        "Content-Length: 254\r\n"
      				        "First boundary: upload\r\n"
					"Content-Disposition: form-data; name=\"_file\"; filename="+arg1+"\r\n"
					"Content-Type: application/ocet-stream\r\n\r\n"
					"Data: "+arg2+"\r\n"
					"Content boundary: \r\nupload\r\n").c_str();

	send(Socket, header, strlen(header), 0);s
					
	char buffer[10000];
	recv(Socket, buffer, 10000, 0);

	closesocket(Socket);
		WSACleanup();
	return 0;
}

Co tu zrobić aby plik był wysyłany?

2

Ten kod się nawet nie kompiluje. Po usunięciu nadmiarowego s, jeśli się skompiluje to:

host = gethostbyname("host");

^ niespecjalnie ma sens.


    char* header = (char*)("POST / HTTP/1.1\r\n"
                    "Host: host\r\n"
                    "Accept: text/html,aplication/xhtml+xml,application/xml;q=9,*/*;q=0.8\r\n"
                            "Content-Type: multipart/form-data; boundary=upload\r\n"
                            "Content-Length: 254\r\n"
                            "First boundary: upload\r\n"
                    "Content-Disposition: form-data; name=\"_file\"; filename="+arg1+"\r\n"
                    "Content-Type: application/ocet-stream\r\n\r\n"
                    "Data: "+arg2+"\r\n"
                    "Content boundary: \r\nupload\r\n").c_str();

Po tym wyrażeniu header wskazuje na pamięć, która została zwolniona. Jakikolwiek jej odczyt to UB i może dać "losowe" rezultaty. Tutaj szukałbym błędu.

0

W C++ nie tak dodaje się napisy. Ty dodajesz char *, więc to się nie ma prawa zbudować.
Użyj stringstream.
Na dodatek używasz mutipart niezgodnie ze standardem. Nie widzę --upload i --upload--.
Użyj wireshark by się upewnić, że na pewno wysyłasz coś zgodnego z http.

1

???

                "Content-Type: application/ocet-stream\r\n\r\n"
                "Data: "+arg2+"\r\n"

skończyłeś header właśnie na Content-Type 2x \r\n\r\n (wyjaśnione w komentarzach ostatecznie ).

1.) SOCKET Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); Zaleca się wpisać 0 zamiast IPPROTO_TCP.

2.) gethostbyname -> zaleca się używania getaddrinfo i reszte.

3.) "xxx" to jest już c string (char *) nie trzeba tego zamieniać na cstring a potem castować na char *

4.) W TCP raczje używa się read/write.

5.) brak wysłania FIN, zamiast tego zachowanie jakby client zcrashował.

6.) Umyka mi gdzie (kiedy) my właściwie wysyłamy tą date. Podajesz wielkość content i co dalej?

1

Swoja drogą rzeźbienie tego w taki sposób to czysty masochizm. Nie lepiej użyć jakiegoś bardziej wysokopoziomowego API? Np POCO?

0

Kod po poprawie wygląda tak w Wireshark nie ma pakietów jeśli dodam linijki od Content-Disposition jesli ją usunę wraz z Content-Disposition to wtedy pakiet jest wysyłany, czy POCO jest na GCC?

 int HTTP_Upload(string arg1, string arg2) {
	WSADATA wsaData;

	if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
		return 1;
	}

	SOCKET Socket = socket(AF_INET, SOCK_STREAM, AF_UNSPEC);

	struct hostent *host;
	host = gethostbyname("host");
	
	if (host == NULL) {
		return 1;
	}

	SOCKADDR_IN SockAddr;
	SockAddr.sin_port = htons(80);
	SockAddr.sin_family = AF_INET;
	SockAddr.sin_addr.s_addr = *((unsigned long*)host->h_addr);

	if(connect(Socket, (SOCKADDR*)(&SockAddr), sizeof(SockAddr)) != 0) {
		return 1;
	}

	char* header = (char*)malloc(2048);
	strcpy(header, "POST / HTTP/1.1\r\n");
	strcat(header, "Host: host\r\n");
	strcat(header, "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; rv:52.0) Gecko/20100101 Firefox/52.0\r\n");
	strcat(header, "Accept: text/html,aplication/xhtml+xml,application/xml;q=9,*/*;q=0.8\r\n");
	strcat(header, "Accept-Language: pl, en-US;q=0.7,en;q=0.3\r\n");
	strcat(header, "Accept-Encoding: gzip, deflate\r\n");
	strcat(header, "DNT: 1\r\n");
	strcat(header, "Connetion: keep-alive\r\n");
	strcat(header, "Upgrade-Insecure-Requests: 1\r\n");
    strcat(header, "Content-Type: multipart/form-data; boundary=boundary\r\n");
    strcat(header, "Content-Length: ");
	strcat(header, to_string(arg2.length()).c_str());
    strcat(header, "\r\n--boundary\r\n");
	strcat(header, ("Content-Disposition: form-data; name=\"_file\"; filename="+arg1+"\r\n").c_str());
	strcat(header, "Content-Type: application/octet-stream\r\n\r\n");
	strcat(header, arg2.c_str());
	strcat(header, "\r\n--boundary--\r\n");

	send(Socket, header, strlen(header), 0);
	free(header);	

	closesocket(Socket);
		WSACleanup();
	return 0;
}

1 użytkowników online, w tym zalogowanych: 0, gości: 1