#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;
}
Соседние файлы в папке MultiProcessUDPClient
  • #
    15.06.20145.8 Кб46main.cpp
  • #
    15.06.20141.89 Кб45md5.h
  • #
    15.06.20147.14 Кб45MD5.lib
  • #
    15.06.20144.13 Кб45MultiProcessUDPClient.vcxproj
  • #
    15.06.20141.31 Кб45MultiProcessUDPClient.vcxproj.filters
  • #
    15.06.2014143 б45MultiProcessUDPClient.vcxproj.user