Добавил:
Kaz
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:
#include <winsock.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <string>
#include <fstream>
#include <iostream>
#include <sstream>
#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 * 64 - 20 - 8
using namespace std;
int PORT = 10001;
char* IP = "192.168.1.2";
struct sockaddr_in server;
char Message[MESSAGE_LENGTH];
int addrLength = sizeof(struct sockaddr_in);
int messageLength = 0;
void Initialization()
{
WSADATA WsaDat;
if (WSAStartup(MAKEWORD(1, 1), &WsaDat) != 0)
printf("WSA Initialization failed. Error code: %d", WSAGetLastError());
}
SOCKET CreateSocket()
{
SOCKET Socket = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (Socket != INVALID_SOCKET)
return Socket;
printf("Create socket error. Error code: %d", WSAGetLastError());
return NULL;
}
int setSockOptions(SOCKET sock)
{
ZeroMemory (&server, sizeof (server));
server.sin_family = AF_INET;
server.sin_addr.s_addr = inet_addr(IP);
server.sin_port = htons(PORT);
timeval timeout;
timeout.tv_sec = 20000;
timeout.tv_usec = 0;
setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout));
//setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*)&timeout, sizeof(timeout));
return 0;
}
int SendData(SOCKET Socket, char* serverMessage)
{
if(sendto(Socket, serverMessage, strlen(serverMessage), 0,(struct sockaddr *)&server,
sizeof(struct sockaddr_in)) != SOCKET_ERROR)
return 0;
return 1;
}
int ParseRequest(string mess)
{
if(mess.find("404") != string::npos) return 4;
if(mess.find("102") != string::npos) return 1;
if(mess.find("HASHES_MISSMATCH") != string::npos) return 9;
return 0;
}
string CheckResponse(string response)
{
if(response.length() < 32)
return response;
string retVal = response.substr(32,response.length());
if(MD5(retVal).hexdigest().compare(response.substr(0,32)) == 0)
return retVal;
return string("HASHES_MISSMATCH");
}
string ReceiveData(SOCKET Socket)
{
ZeroMemory(Message,MESSAGE_LENGTH);
if ((messageLength = recvfrom (Socket, Message, MESSAGE_LENGTH, 0,
(struct sockaddr *)&server, &addrLength)) != -1 )
return CheckResponse(string(Message,messageLength));
printf("Recive message error. Error code: %d\n", WSAGetLastError());
return string("404 ERROR\r\n");
}
long getTempFileInfo(string filename)
{
std::ifstream File(filename + ".tmp", ios::in);
if(!File.is_open()) return 0;
char* FileContent = new char[512];
File.read(FileContent,512);
string temp(FileContent,File.gcount());
delete []FileContent;
if(temp.length() < 3 ) return 0;
int offset = temp.find(" = ") + 3;
return atol(temp.substr(offset, temp.find("\n\r",offset)).c_str());
}
int setTempFileInfo(string filename, long offset)
{
string FileName(filename + ".tmp");
FILE* f = fopen(FileName.c_str(), "wt");
if(f == NULL) {printf("Set temp file failed!"); return 1;}
char tmp[128];
string FileLine(filename + " = " + ltoa(offset, tmp,10));
fputs(FileLine.c_str(),f);
fclose(f);
FileLine.clear();
return 0;
}
int SaveFilePart(string file, string content, bool isNew)
{
FILE* f = fopen(file.c_str(),(isNew ? "wb" : "a+b"));
if(f == NULL) {printf("Write file failed!"); return 1;}
fseek(f,0,SEEK_END);
fwrite(content.c_str(),1,content.length(),f);
fflush(f);
fpos_t filelen;
fseek(f,0,SEEK_END);
fgetpos(f,&filelen);
fclose(f);
setTempFileInfo(file,filelen);
return 0;
}
long GetFileSize(SOCKET Socket, string filename)
{
if(!SendData(Socket, (char*)string("INFO\n\r" + filename + "\n\r").c_str()))
return atol(ReceiveData(Socket).c_str());
return 0;
}
int main(int argc, char *argv[])
{
char* file = new char[256];
printf("Input filename for download: ");
scanf("%s", file);
string filename(file);
delete []file;
Initialization();
SOCKET Socket = CreateSocket();
setSockOptions(Socket);
if(Socket != NULL)
{
long filesize = GetFileSize(Socket, filename);
long offset = getTempFileInfo(filename);
do
{
char* tmp = new char(64);
string request("GET\n\r" + filename + "\n\r" + ltoa(offset, tmp , 10) + "\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 == 0 ? true : false);
offset += response.length();
double t = 100 *(double)((double)(offset) / filesize);
printf("Transfered: %.2f%% of %ld bytes\n", t , filesize);
}
while(1);
if(offset == filesize)
remove(string(filename + ".tmp").c_str());
if(offset > 0 && offset < filesize)
setTempFileInfo(filename, offset);
}
closesocket(Socket);
WSACleanup();
getch();
printf ("\n\nDone!\n\n");
return 0;
}