You are on page 1of 10

// UDPFileTransfer.cpp : Defines the entry point for the console application.

//

#include "stdafx.h" #include "SockUDP.h" #include "UDPFileTransfer.h" #include "CRC32.h"

DWORD crc32buf(char *buf, size_t len); void DataRecieved(CSockUDP* sock, LPVOID lpData, int nData); void ConstructAndSend(CSockUDP* sock, eDataType type, LPVOID lpData, int nLen); const char* GetFileName(const char* szPath);

//////////////////////////////////////////////////// bool g_bIsConnected = false; char g_szFileName[128]; FILE* g_file; bool g_bCanContinue = false, g_bSending = false; ////////////////////////////////////////////////////

int main(int argc, char* argv[]) { // Init the winsock before using it if (CSockUDP::InitWinsock() != 0) { printf("Failed to init winsock!"); return 1;

int iChoice = 0;

printf("1 - Server\n2 - Client\nEnter your choice: "); scanf("%d", &iChoice);

if (iChoice == 1) { // Server CSockUDP sockServer; sockServer.CreateSocket(); port 31313 sockServer.SetCallback(&DataRecieved); sockServer.StartListen(); // Listen for incoming data // Create socket with default

// Wait for the data //char szInput[260]; printf("Waiting for the incoming file...\n\n"); while(1) Sleep(100);

sockServer.StopListen(); Sleep(100); } else { // Client

// Ask for remote

char szRemote[512]; printf("Enter IP/Hostname of the remote computer: "); scanf("%s", szRemote);

CSockUDP sockClient; sockClient.CreateSocket(0); any port available sockClient.SetCallback(&DataRecieved); while (!sockClient.SetServerAddress(szRemote, 31313)) { printf("Host not found. Please re-enter IP/Hostname: "); scanf("%s", szRemote); } sockClient.StartListen(); incoming data // Listen for // Use

printf("Connecting...\n");

// Send connect until we got a reply, that means the server is ready while (g_bIsConnected == false) { ConstructAndSend(&sockClient, eDataTypeConnect, NULL, 0); Sleep(500); }

// Stay while connected while (g_bIsConnected) Sleep(500);

sockClient.StopListen(); }

// Terminates the use of winsock dll CSockUDP::DestroyWinsock(); return 0; }

void DataRecieved(CSockUDP* sock, LPVOID lpData, int nData) { // Verify header TUDPHeader* header = (TUDPHeader*)lpData; if (memcmp(header->szID, "IKH", 3) != 0) return; LPVOID pData = (LPVOID)((char*)lpData + sizeof(TUDPHeader));

// Calculate checksum CRC32 crc(pData, header->nLength); if (header->dwCRC32 != crc.Get()) { ConstructAndSend(sock, eDataTypeResend, NULL, 0); return; }

switch (header->type) { case eDataTypeConnect: ConstructAndSend(sock, eDataTypeConnected, NULL, 0);

g_bIsConnected = true; break; case eDataTypeConnected: g_bIsConnected = true; { char szPath[260]; do { // Ask for file input printf("Enter the file path to send or type 'quit' to exit: "); scanf("%s", szPath);

g_bSending = false; g_file = fopen(szPath, "rb"); if (g_file != NULL) { // Prepare the file send request TUDPFileHeader fudpHeader;

strcpy(fudpHeader.szFileName, GetFileName(szPath)); fseek(g_file , 0 , SEEK_END); fudpHeader.nFileSize = ftell(g_file); rewind(g_file);

// Send and pause until send complete g_bSending = true; ConstructAndSend(sock, eDataTypeFileHeader, &fudpHeader, sizeof(TUDPFileHeader));

while (g_bSending) Sleep(1); } else { printf("Error opening file\n"); } } while (_stricmp(szPath, "quit") != 0); } break; case eDataTypeResend: sock->ResendData(); break; case eDataTypeQuit: g_bIsConnected = false; break; case eDataTypeFileHeader: { TUDPFileHeader* fudpHeader = (TUDPFileHeader*)pData; char szReply[32]; printf("Do you want to accept '%s', %d bytes? (y/n): ", fudpHeader->szFileName, fudpHeader->nFileSize); scanf("%s", &szReply); if (szReply[0] == 'y' || szReply[0] == 'Y') { g_file = fopen(fudpHeader->szFileName, "wb"); if (g_file) ConstructAndSend(sock, eDataTypeFileReplyAccept, NULL, 0); else

ConstructAndSend(sock, eDataTypeFileReplyReject, NULL, 0); } else { ConstructAndSend(sock, eDataTypeFileReplyReject, NULL, 0); } } break; case eDataTypeFileTransfer: { TUDPFileTransfer* fudpTx = (TUDPFileTransfer*)pData; fseek(g_file, fudpTx->nFileOffset, SEEK_SET); fwrite(fudpTx->szData, 1, fudpTx->nLength, g_file); ConstructAndSend(sock, eDataTypeFileReplyOK, NULL, 0); } break; case eDataTypeFileReplyAccept: printf("Server accepted the file. Sending...\n"); // Begin transfer { TUDPFileTransfer fudpTx; long lSize, lCurSize;

// Get file size fseek(g_file , 0 , SEEK_END); lSize = ftell(g_file); rewind(g_file);

lCurSize = 0; fudpTx.nFileOffset = 0; while(lCurSize < lSize) { g_bCanContinue = false;

fudpTx.nLength = (lSize - lCurSize > sizeof(fudpTx.szData) ? sizeof(fudpTx.szData) : lSize - lCurSize); fread(fudpTx.szData, 1, sizeof(fudpTx.szData), g_file); ConstructAndSend(sock, eDataTypeFileTransfer, &fudpTx, sizeof(TUDPFileTransfer)); fudpTx.nFileOffset += sizeof(fudpTx.szData);

lCurSize += sizeof(fudpTx.szData); while (g_bCanContinue == false) Sleep(1); }

// Notify end of file ConstructAndSend(sock, eDataTypeFileReplyFinish, NULL, 0); g_bSending = false; printf("File sent\n"); } break; case eDataTypeFileReplyReject: // Denied, print some message and close the file g_bSending = false;

printf("File denied\n"); fclose(g_file); break; case eDataTypeFileReplyOK: g_bCanContinue = true; break; case eDataTypeFileReplyFinish: fclose(g_file); break; } }

void ConstructAndSend(CSockUDP* sock, eDataType type, LPVOID lpData, int nLen) { TUDPHeader header; CRC32 crc; char *szBuff;

header.szID[0] = 'I'; header.szID[1] = 'K'; header.szID[2] = 'H'; header.type = type; header.nLength = nLen;

// Calculate the checksum crc.Hash(lpData, nLen);

header.dwCRC32 = crc.Get();

// Allocate and fill buffer int nBuffLen = sizeof(TUDPHeader) + nLen; szBuff = new char[nBuffLen]; memcpy(szBuff, &header, sizeof(TUDPHeader)); memcpy(szBuff+sizeof(TUDPHeader), lpData, nLen);

sock->SendData(szBuff, sizeof(TUDPHeader) + nBuffLen); delete[] szBuff; }

const char* GetFileName(const char* szPath) { unsigned int j = 0; for (unsigned int i=0; i<strlen(szPath); i++) { if (szPath[i] == '\\') j = i; }

return szPath + j + 1; }

You might also like