Добавил:
Kaz
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:
#include <winsock.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <string>
#include <fstream>
#include <iostream>
#include <conio.h>
#include "md5.h"
#pragma comment (lib, "ws2_32")
#pragma comment (lib,"md5.lib")
#define MAX_CONNECTION_COUNT 2
#define MESSAGE_LENGTH 1024 * 4 + 32
using namespace std;
int PORT = 10001;
char* IP = "192.168.1.2";
struct sockaddr_in server;
void Initialization()
{
WSADATA WsaDat;
if (WSAStartup(MAKEWORD(1, 1), &WsaDat) != 0)
printf("WSA Initialization failed. Error code: %d", WSAGetLastError());
}
SOCKET CreateSocket()
{
SOCKET sock;
if (INVALID_SOCKET == (sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP) ) )
{
printf("Create socket error. Error code: %d", WSAGetLastError());
return NULL;
}
else return sock;
}
int setSockOptions(SOCKET sock)
{
timeval timeout;
timeout.tv_sec = 30000;
timeout.tv_usec = 0;
//setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout));
//setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*)&timeout, sizeof(timeout));
ZeroMemory (&server, sizeof (server));
server.sin_family = AF_INET;
server.sin_addr.s_addr = inet_addr(IP);
server.sin_port = htons(PORT);
return 0;
}
int SendData(SOCKET Socket, char* serverMessage)
{
if(sendto(Socket, serverMessage, strlen(serverMessage), 0,
(struct sockaddr *)&server,sizeof(struct sockaddr_in)) == SOCKET_ERROR)
{
closesocket(Socket);
return 1;
}
return 0;
}
/////------------------------------
char* GetFileData(string fileName, long position, long offset)
{
std::ifstream file(fileName, ios::in |ios::binary);
if (!file.is_open())
return NULL;
char* memblock;
file.seekg (position, ios::beg);
file.read (memblock, offset);
file.close();
return memblock;
}
int ParseRequest(string mess)
{
int index = mess.find("404");
if(index != string::npos)
return 4;
index = mess.find("102");
if(index != string::npos)
return 1;
index = mess.find("HASHES_MISSMATCH");
if(index != string::npos)
return 9;
return 0;
}
string CheckResponse(string response)
{
if(response.length() < 32)
return response;
string tmp1 =response.substr(0,32);
string tmp2 = MD5(response.substr(32,response.length())).hexdigest();
if(tmp1.compare(tmp2) == 0)
{
return response.substr(32,response.length());
}
return string("HASHES_MISSMATCH");
}
string ReceiveData(SOCKET Socket)
{
char* tmpMessage = new char[MESSAGE_LENGTH];
int messageLength;
int server_length = sizeof(struct sockaddr_in);
if ((messageLength = recvfrom (Socket, tmpMessage, MESSAGE_LENGTH, 0,
(struct sockaddr *)&server, &server_length)) == -1 )
{
printf("Recive message error. Error code: %d", WSAGetLastError());
closesocket(Socket);
return string("404 ERROR\r\n");
}
string response(tmpMessage,messageLength);
delete []tmpMessage;
return CheckResponse(response);
}
long getTempFileInfo(string filename)
{
string tempFileName(filename + ".tmp");
std::fstream tempFile(tempFileName, ios::out | ios::in | ios::app);
if(!tempFile.is_open()){
printf("Could not create temorary file!\n\r");
return -1;
}
tempFile.seekg (0, ios::end);
int length = tempFile.tellg();
tempFile.seekg (0, ios::beg);
char* tempFileContent = new char[length];
memset(tempFileContent,0,length);
tempFile.read(tempFileContent,length);
string temp(tempFileContent);
delete []tempFileContent;
if(temp.length() < 1 )
{
string tempFileLine(filename);
tempFileLine += " = 0\n\r";
tempFile.write(tempFileLine.c_str(),tempFileLine.length());
tempFile.close();
return 0;
}
int offset = temp.find(filename);
return atol(temp.substr(offset + filename.length() + 3, temp.find("\n\r",offset)).c_str());
}
int setTempFileInfo(string filename, long offset)
{
string tempFileName(filename + ".tmp");
std::fstream tempFile(tempFileName, ios::out | ios::trunc);
if(!tempFile.is_open()){
printf("Could not create temorary file!\n\r");
return -1;
}
string tempFileLine(filename);
tempFileLine += " = ";
char* tmp = new char(64);
tempFileLine += ltoa(offset, tmp , 10);
tempFileLine += "\n\r";
tempFile.write(tempFileLine.c_str(),tempFileLine.length());
tempFile.close();
return 0;
}
int SaveFilePart(string file, string content)
{
std::fstream File(file, ios::out | ios::app | ios::binary);
if(!File.is_open()){
printf("Could not create file!\n\r");
return 1;
}
File.seekg(0, ios::end);
File.write(content.c_str(),content.length());
long offset = File.tellg();
File.close();
setTempFileInfo(file, offset);
return 0;
}
int main(int argc, char *argv[])
{
char* file = new char[256];
long filesize = 0;
printf("Input filename for download: ");
scanf("%s", file);
string filename(file);
delete []file;
long offset = getTempFileInfo(filename);
Initialization();
SOCKET Socket = CreateSocket();
setSockOptions(Socket);
if(Socket != NULL)
{
string request("INFO\n\r" + filename + "\n\r");
if(SendData(Socket, (char*)request.c_str()))
{
closesocket(Socket);
WSACleanup();
return 0;
}
string info(ReceiveData(Socket));
filesize = atol(info.c_str());
do
{
string request("GET\n\r" + filename + "\n\r");
char* tmp = new char(64);
request += ltoa(offset, tmp , 10);
request += "\n\r";
if(SendData(Socket, (char*)request.c_str()))
{
break;
}
string response(ReceiveData(Socket));
if(response.length() < 30)
{
int status = ParseRequest(response);
if(status == 1)
{
printf(response.c_str());
break;
}
if(status == 4)
{
printf("Error : %s",response.c_str());
break;
}
if(status == 9)
{
continue;
}
}
SaveFilePart(filename,response);
offset += response.length();
printf("Transfered: %.1f%% of %ld bytes\n", (double)((double)(100 * offset) / filesize), filesize);
}
while(1);
}
remove(filename.append(".tmp").c_str());
closesocket(Socket);
WSACleanup();
printf ("\n\nDone!\n\n");
return 0;
}