#include <winsock.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <string>
#include <fstream>
#include <ctime>
#include <conio.h>
#include "md5.h"
#pragma comment (lib, "ws2_32") 
#pragma comment (lib,"md5.lib")
#define		MAX_CLIENTS    3
#define		MESSAGE_LENGTH			1024 * 64 - 20 - 8 - 33
#define		IP						"192.168.1.2"
#define		PORT					10001
using namespace std;
long sended = 0;
struct sockaddr_in server;

char Message[MESSAGE_LENGTH];
char memblock[MESSAGE_LENGTH+1];
int addrLen = (int)sizeof(struct sockaddr_in);

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)))
    return sock;
    printf("Create socket error. Error code: %d", WSAGetLastError());
    return NULL;
}

void BindSocket(SOCKET sock)
{
    ZeroMemory (&server, sizeof (server));
    server.sin_family = AF_INET;
    server.sin_addr.S_un.S_addr = inet_addr (IP);
    server.sin_port = htons(PORT);
    if (SOCKET_ERROR == bind (sock, (sockaddr* ) &server, sizeof (server)))
        printf("Bind socket error. Error code: %d", WSAGetLastError());
    timeval timeout;
    timeout.tv_sec = 30000;
    timeout.tv_usec = 0;
    int buffsize = MESSAGE_LENGTH;
    //setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO,  (char*)&timeout, sizeof(timeout)); 
    setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*)&timeout, sizeof(timeout));
    //setsockopt(sock, SOL_SOCKET, SO_RCVBUF,(const char *)&buffsize, sizeof(buffsize));
}


bool SendData(SOCKET clientSocket, char* serverMessage)
{ 
    if(sendto(clientSocket, serverMessage, strlen(serverMessage), 0, NULL, 0) != SOCKET_ERROR)
    return true;
    return false;
}

int GetFileInfo(SOCKET Socket, string fileName)
{
    std::ifstream file(fileName, ios::in | ios::binary);
    if (!file.is_open()) 
	{
		SendData(Socket, "404 FILE NOT FOUND\r\n\0");
		return 4;
	}
    file.seekg (0, ios::end);
    long readed = file.tellg();
    file.close();
    char tmp[256]; 
    SendData(Socket, (char*)string(ltoa(readed,tmp,10)).c_str());
    return 0;
}

int GetFileData(SOCKET sock, string fileName, long position)
{
    HANDLE file = CreateFileA(fileName.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED  , NULL);
    OVERLAPPED Read;
    ZeroMemory(&Read,sizeof(Read));
    Read.hEvent = CreateEvent(NULL, FALSE, FALSE ,NULL);
    Read.Offset = position;
    ReadFile(file, memblock, MESSAGE_LENGTH, NULL , &Read);
    DWORD dw = WaitForSingleObject(Read.hEvent, INFINITE);
    DWORD readed = 0;
    if(dw ==  WAIT_OBJECT_0)
    {
        if (GetOverlappedResult(file,&Read, &readed, TRUE) != 0)
        {
            CloseHandle(file);
            if(readed >= 0)
            {
                 char tmp[MESSAGE_LENGTH+33];
                 char *tmp2 =strdup(MD5(string(memblock, readed)).hexdigest().c_str());
                 for (int i = 0; i < 32; i++)
                 {
                 	tmp[i] = tmp2[i];
                 }
                 for(int i = 32; i < readed + 32; i++)
                 {
                 	tmp[i] = memblock[i-32];
                 }
                 readed += 32;
                 tmp[readed] = '\0';
                 if(sendto(sock, tmp, readed, 0, NULL, 0) == SOCKET_ERROR)
                 {
                 	closesocket(sock);
                 	return 1;
                 }
                 sended += readed;
                 return 0;
            }
            else 
            {
                if(position == 0)
                {
                    SendData(sock,"404 FILE NOT FOUND\r\n\0");
                    return 4;
                }
                SendData(sock, "102 ALL SENDED\r\n\0");
                return 1;
            }
        }
        else
        {
            CloseHandle(file);
            switch(GetLastError())
            {
                case ERROR_HANDLE_EOF:
                    SendData(sock, "102 ALL SENDED\r\n\0");
                    return 1;
                default:
                    string t("404 ERROR SYS_CODE_");
                    char tmp[6];
                    t += itoa(GetLastError(),tmp,10);
                    SendData(sock, (char*)t.c_str());
                    return 4;
            }
        }
    }
    CloseHandle(file);
    string t("404 ERROR SYS_CODE_");
    char tmp[6];
    t += itoa(GetLastError(),tmp,10);
    SendData(sock, (char*)t.c_str());
    return 4;
}

int ParseRequest(SOCKET Socket, string message)
{
    if(message.length() < 1) return 4;
    string request[3] = {"","",""};
    int index1 = 0, index2 = 0, i = 0;
    while(1)
    {
        index2 = message.find("\n\r", index2);
        if(index2 > 0 && index2 < message.length())
        {
            request[i] = message.substr(index1 ,index2 - index1);
            index2 += 2;
            index1 = index2;
            i++;
            if(i == 3) break;
        }
        else break;
    }
    if(request[0].compare("GET") == 0)
        return GetFileData(Socket, request[1], atol(request[2].c_str()));
    if(request[0].compare("INFO") == 0)
        return GetFileInfo(Socket, request[1]);
    else
    {
        SendData(Socket, "403 WRONG REQUEST\r\n\0");
        return 4;
    }
    return 0;
}

string ReciveData(SOCKET Socket)
{
    ZeroMemory(Message,MESSAGE_LENGTH);
    int messageLength;
    if ((messageLength = recvfrom(Socket, Message, MESSAGE_LENGTH, 0, NULL,0)) == -1 )
    {
        printf("Recive message error. Error code: %d\n", WSAGetLastError());
        return string();
    }
    string response(Message,messageLength);
    return response;
}

int main(int argc, char *argv[])
{
    fd_set fdRead,fdWorkingRead;
    SOCKET Sockets[MAX_CLIENTS];
    char tmp[128];
    do
	{
		Initialization();
		SOCKET Socket = CreateSocket();
		if(Socket != NULL)
		{
            ZeroMemory(Sockets,sizeof(SOCKET) * MAX_CLIENTS);
			BindSocket(Socket);
            FD_ZERO(&fdRead);
            FD_ZERO(&fdWorkingRead);
			FD_SET(Socket, &fdRead);
            int s = 0;
            while(1)
            {
                //Sleep(100);
                CopyMemory(&fdWorkingRead, &fdRead, sizeof(fd_set));
                if (s = select(NULL, &fdWorkingRead, NULL, NULL, NULL) == SOCKET_ERROR)
                {
                    printf("Error select(): %d\n", WSAGetLastError());
                    getch();
                }
                if (FD_ISSET(Socket,&fdWorkingRead))
                {
                    sockaddr_in client;
                    int len = recvfrom(Socket,tmp,128,0,(struct sockaddr *)&client, &addrLen);
                    string t(tmp, len);
                    if(t.compare("CONNECT") == 0)
                    for(int i = 0; i < MAX_CLIENTS; i++)
                    {
                        if(Sockets[i] == NULL)
                        {
                            Sockets[i] = CreateSocket();
                            connect(Sockets[i],(struct sockaddr *)&client,addrLen);
                            FD_SET(Sockets[i], &fdRead);
                            len = sendto(Sockets[i],"101 CONNECTED",13,0,NULL,0);
                            break;
                        }
                    }
                    
                }
                for (int i = 0; i < MAX_CLIENTS; i++)
                {
                    if (FD_ISSET(Sockets[i],&fdWorkingRead))
                    {
                       if(ParseRequest(Sockets[i],ReciveData(Sockets[i])) != 0 )
                       {
                           FD_CLR(Sockets[i],&fdRead);
                           closesocket(Sockets[i]);
                           printf("Close Socket %d\n", i);
                           Sockets[i] = NULL;
                           getch();
                       }
                       sockaddr_in cl;
                       getpeername(Sockets[i], (struct sockaddr *)&cl, &addrLen);
                       printf("Recived from client %d:  %s : %d\n", i, inet_ntoa(cl.sin_addr),ntohs(cl.sin_port));
                    }
                }
                FD_ZERO(&fdWorkingRead);
                //for (int i = 0; i < MAX_CLIENTS; i++)
                //    if (Sockets[i] != 0) FD_SET(Sockets[i], &fdRead);
                
            
            }
            closesocket (Socket);
		}
		else closesocket (Socket);
		WSACleanup();
	}while(1);
	return 0;
}
Соседние файлы в папке MultiplexUDPServer
  • #
    15.06.20148.77 Кб45main.cpp
  • #
    15.06.20141.89 Кб46md5.h
  • #
    15.06.20147.14 Кб45MD5.lib
  • #
    15.06.20144.12 Кб45MultiplexUDPServer.vcxproj
  • #
    15.06.20141.31 Кб45MultiplexUDPServer.vcxproj.filters
  • #
    15.06.2014143 б45MultiplexUDPServer.vcxproj.user