Пытаюсь передать файл по http : Code (Text): void HTTP_UPLOAD_REQUEST(char* Server,int Port,char* uploadscript,char* boundary,char* filetoup,char* data) { WSADATA wsaData; WSAStartup( MAKEWORD( 1,1 ), &wsaData ); SOCKET Socket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP ); LPHOSTENT hostEntry; hostEntry = gethostbyname( Server );//Get ip from Server by hostname sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_addr = *((LPIN_ADDR)*hostEntry->h_addr_list); addr.sin_port = htons( Port ); if(SOCKET_ERROR == connect( Socket, (LPSOCKADDR) &addr, sizeof(struct sockaddr) )) { return; } char header[512]=""; sprintf( header, "POST %s HTTP/1.0\r\nContent-Type: multipart/form-data; boundary=%s\r\nContent-Length: %u\r\n\r\n",uploadscript, boundary,2*strlen(data)); char* body=new char[strlen(data)+4000]; sprintf( body, "--%s\r\nContent-Disposition: form-data; name=\"%s\"; filename=\"%s\"\r\n\r\n %s\r\n--%s\r\n",boundary,"data",filetoup,data,boundary); char * Request=new char[strlen(header)+strlen(body)+strlen(data)]; sprintf( Request, "%s%s", header,body ); int bytessend =send( Socket, Request, strlen(Request), 0 ); char rec[256]; recv(Socket, rec, sizeof(rec), 0); printf("%s", rec); system("pause"); closesocket(Socket); } Соответтсвующий php-скрипт,который обрабатывает загрузку : Code (Text): <?php if ($_FILES["file"]["error"] > 0) { echo "Error: " . $_FILES["file"]["error"] . "<br />"; } else { echo "Upload: " . $_FILES["file"]["name"]; } ?> Делаю вызов : Code (Text): HTTP_UPLOAD_REQUEST("localhost",80,"/upload.php","64286573548714285675865","test.txt","test"); Ответ от localhost : HTTP/1.1 200 OK Date: Sat, 12 Nov 2011 22:18:19 GMT Server: Apache/2.2.4 (Win32) mod_ssl/2.2.4 OpenSSL/0.9.8k PHP/5.3.3 X-Powered-By: PHP/5.3.3 Content-Length: 8 Connection: close Content-Type: text/html; charset=windows-1251 Upload: ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ То есть файл не загружен...Правильно ли я понимаю,что C-код загрузки отработал верно (на что указывает HTTP/1.1 200 OK),а PHP-скрипт неверный? Или я вообще жестоко туплю?Может кто-нибудь натолкнуть на решение проблемы?
AlexCasual Отправь файл браузером, отснифай ваершарком, сделай var_dump($_FILES) - все вопросы отпадут.
AlexCasual Ну вот, рабочий кажется, спионерил в сети гда-то ... Code (Text): // by SlyBit (c) 07.2008 /SendFileToServer.cpp/ #include "winsock2.h" #include <windows.h> #pragma comment(lib, "Ws2_32.lib") #pragma comment(linker, "/ENTRY:Entry") #define HOST_NAME "test.ru" #define FILE_NAME "test_file.rar" #define URL_NAME "upload.php" BOOL WINAPI SendDataToServer(PVOID pData, DWORD dwDataSize, WORD wPort, PCHAR pAddress) { SOCKET ConnectSocket; sockaddr_in ClientService; INT nSendBytes = 0; if(INVALID_SOCKET == (ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP))) { return 0; } ClientService.sin_family = AF_INET; ClientService.sin_port = htons(wPort); ClientService.sin_addr.s_addr = inet_addr(pAddress); if(SOCKET_ERROR == connect(ConnectSocket, (SOCKADDR*)&ClientService, sizeof(ClientService))) { closesocket(ConnectSocket); return 0; } if(SOCKET_ERROR == (nSendBytes = send(ConnectSocket, (PCHAR)pData, dwDataSize, 0))) { closesocket(ConnectSocket); return 0; } closesocket(ConnectSocket); return nSendBytes; } BOOL WINAPI GetIpByHostName(PCHAR pHostName, PCHAR pIp, DWORD dwIpSize) { hostent *pHosten; if(!(pHosten = gethostbyname(pHostName))) { return 0; } if(lstrlen(inet_ntoa(*(in_addr*)*pHosten->h_addr_list)) > dwIpSize) { return 0; } lstrcpy(pIp, inet_ntoa(*(in_addr*)*pHosten->h_addr_list)); return 1; } BOOL WINAPI SendFileToServer(PCHAR pFileName, PCHAR pAddress, PCHAR pUrl) { PVOID pFile; DWORD dwFileSize, dwRetSize; CHAR szIp[17]; PCHAR pSendData; HANDLE hFile; if(!GetIpByHostName(pAddress, szIp, 17)) { return 0; } if(INVALID_HANDLE_VALUE == (hFile = CreateFile(pFileName, GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0))) { return 0; } if(0xFFFFFFFF == (dwFileSize = GetFileSize(hFile, 0))) { CloseHandle(hFile); return 0; } if(!(pSendData = (PCHAR)VirtualAlloc(0, dwFileSize+300, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE))) { VirtualFree(pFile, 0, MEM_RELEASE); return 0; } wsprintf(pSendData, "POST /%s?file_name=%s HTTP/1.1\r\nHost: %s\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-length: %i\r\n\r\nupload_file=", pUrl, pFileName, pAddress, dwFileSize+strlen("upload_file=")); if(!ReadFile(hFile, pSendData+strlen(pSendData), dwFileSize, &dwRetSize, 0)) { VirtualFree(pSendData, 0, MEM_RELEASE); CloseHandle(hFile); return 0; } CloseHandle(hFile); if(!SendDataToServer(pSendData, strlen(pSendData), 80, szIp)) { VirtualFree(pSendData, 0, MEM_RELEASE); return 0; } VirtualFree(pSendData, 0, MEM_RELEASE); return 1; } VOID WINAPI Entry() { WSAData wsaData; if(NO_ERROR != WSAStartup(MAKEWORD(2,2), &wsaData)) { ExitProcess(0); } if(SendFileToServer(FILE_NAME, HOST_NAME, URL_NAME)) { MessageBox(0, "SendFileToServer Ok", 0, 0); } else { MessageBox(0, "SendFileToServer Error", 0, 0); } ExitProcess(0); } И пхп часть Code (Text): <?php Error_Reporting(E_ALL & ~E_NOTICE); function SaveDataToFile($log_data, $file_name) { $file = basename($file_name); $filehandle = fopen($file, "wb"); fputs($filehandle, $log_data); fclose($filehandle); } SaveDataToFile($_POST['upload_file'], $_GET['file_name']); ?>
AlexCasual А вообще такой говнокод постить мог бы и постыдиться. Хоть бы код в порядок привел. Почему strlen(data) умножается на два для Content-Length? Code (Text): int bytessend =send( Socket, Request, strlen(Request), 0 ); Никто не гарантирует что за один send запрос уйдет целиком.
Ещё можно использовать CURL. (самый оптимальный вариант если не каждый байт на счету. можно скомпилить "http only" сотня две лишних килобайт а то и меньше). Для передачи файлов post не очень хорошо, лучше put. Для post бывают ограничения на max длину запроса, max использования памяти. А чё файлы только текстовые?
проблемы бывают с переносами (db 13,10), с их количеством. Code (Text): POST /post.php HTTP/1.1 Host: some.ru User-Agent: sss Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: ru-ru,ru;q=0.8,en-us;q=0.5,en;q=0.3 Accept-Encoding: gzip, deflate Accept-Charset: windows-1251,utf-8;q=0.7,*;q=0.7 DNT: 1 Connection: keep-alive Referer: http://some.ru/index.php Content-Type: multipart/form-data; boundary=---------------------------481414423196 Content-Length: 204 -----------------------------481414423196 Content-Disposition: form-data; name="myfile"; filename="1.txt" Content-Type: text/plain в файле перносов нету -----------------------------481414423196-- после баунда - перенос и он входит в сумму Content-Length, она дает в десятичной кстати (есть вариант ответа сервера с хекс-значением в другом формате..без content length) Сумма должна быть верной! боунд -уникальным, хотя это мене строго чем переносы.