├── Client ├── Client.cpp └── json.hpp ├── README.md ├── Server ├── Clinet.hpp ├── Connection.hpp ├── FileProccess.hpp ├── Main.cpp └── json.hpp ├── SimpleClientSock.cpp ├── SimpleSingleClientServerSock.cpp ├── SimpleSingleThreadMultiClientServer.cpp └── TCP ├── Client ├── ClientConnection.cpp ├── ClientConnection.h ├── FileHandler.h ├── PACKET.cpp ├── PACKET.h ├── Queue.cpp ├── Queue.h ├── Serialize.h └── Source.cpp ├── Server ├── Client.h ├── FileHandler.h ├── PACKET.h ├── Queue.cpp ├── Queue.h ├── Serialize.h ├── TCPListener.cpp ├── TCPListener.h └── source.cpp └── StepByStep ├── E01 ├── Client │ ├── ClientConnection.cpp │ ├── ClientConnection.h │ ├── Packets.h │ └── Source.cpp ├── ReadMe.md └── Server │ ├── Packets.h │ ├── Source.cpp │ ├── TCPListener.cpp │ └── TCPListener.h ├── E02 ├── Client │ ├── Packets.h │ ├── Serialize.h │ ├── Source.cpp │ ├── TCPListener.cpp │ └── TCPListener.h ├── ReadMe.md └── Server │ ├── Packets.h │ ├── Serialize.h │ ├── Source.cpp │ ├── TCPListener.cpp │ └── TCPListener.h ├── E03 ├── Client │ ├── ClientConnection.cpp │ ├── ClientConnection.h │ ├── FileHandler.h │ ├── Packets.h │ ├── Queue.cpp │ ├── Queue.h │ ├── Serialize.h │ └── Source.cpp └── Server │ ├── FileHandler.h │ ├── Packets.h │ ├── Queue.cpp │ ├── Queue.h │ ├── Serialize.h │ ├── Source.cpp │ ├── TCPListener.cpp │ └── TCPListener.h └── E04-Final ├── Cleint ├── Cleint.sln ├── Cleint.vcxproj ├── Cleint.vcxproj.filters ├── Cleint.vcxproj.user ├── CleintConnection.cpp ├── CleintConnection.h ├── FileHandler.h ├── Packets.h ├── Queue.cpp ├── Queue.h ├── Serialize.h └── Source.cpp ├── ServerDLL ├── FileHandler.h ├── Packets.h ├── Queue.cpp ├── Queue.h ├── Serialize.h ├── ServerDLL.vcxproj ├── ServerDLL.vcxproj.filters ├── ServerDLL.vcxproj.user ├── Source.cpp ├── Source.h ├── TCPListener.cpp ├── TCPListener.h ├── dllmain.cpp ├── framework.h ├── pch.cpp └── pch.h └── SocketUI ├── MyForm.cpp ├── MyForm.h ├── MyForm.resx ├── SocketUI.sln ├── SocketUI.vcxproj ├── SocketUI.vcxproj.filters └── SocketUI.vcxproj.user /Client/Client.cpp: -------------------------------------------------------------------------------- 1 | 2 | //----------------------------------------------------- 3 | // Design Name : Just For Test Server 4 | // File Name : Client.cpp 5 | // Function : Bad Code 6 | // Coder : Amirreza Tavakoli 7 | //----------------------------------------------------- 8 | #define _CRT_SECURE_NO_WARNINGS 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include "json.hpp" 21 | #include 22 | #include "ProgressBar1.hpp" 23 | #pragma comment (lib, "Ws2_32.lib") 24 | using namespace std; 25 | using Json = nlohmann::json; 26 | #define BUFFERLENGTH 80 * 1024 27 | #define ServerPORT 6969 28 | #define ServerIP "127.0.0.1" 29 | SOCKET MySocket; 30 | sockaddr_in My_address; 31 | 32 | 33 | enum Header 34 | { 35 | FileInfo, 36 | Message, 37 | File, 38 | SendAuthorize 39 | }; 40 | 41 | string GetFileName(string path) 42 | { 43 | for (int i = path.length(); i >= 0; i--) 44 | if (path[i] == '\\') 45 | return path.substr(i + 1); 46 | return path; 47 | } 48 | string GetFileExtention(string path) 49 | { 50 | string filename = GetFileName(path); 51 | size_t i = filename.rfind('.', filename.length()); 52 | if (i != string::npos) { 53 | return(filename.substr(i, filename.length() - i)); 54 | } 55 | } 56 | string GetFileNameWhitOutExtention(string path) 57 | { 58 | string filename = GetFileName(path); 59 | size_t i = filename.rfind('.', filename.length()); 60 | if (i != string::npos) { 61 | return(filename.substr(0, i)); 62 | } 63 | } 64 | inline string TempPath(string Filename, string Extention = ".tmp") 65 | { 66 | return Filename + Extention; 67 | } 68 | inline bool IsFileExist(const string& name) { 69 | ifstream f(name.c_str()); 70 | return f.good(); 71 | } 72 | bool ConvertTmpToStableFile(const string& tmppath, const string& destinationpath) 73 | { 74 | if (!IsFileExist(tmppath)) 75 | return 0; 76 | if (rename(tmppath.c_str(), destinationpath.c_str()) != 0) 77 | ConvertTmpToStableFile(tmppath, GetFileNameWhitOutExtention(destinationpath) + "_Copy" + GetFileExtention(destinationpath)); 78 | else 79 | return 1; 80 | } 81 | 82 | 83 | 84 | bool SocketConfig() 85 | { 86 | 87 | 88 | WSADATA Windows_Socket_info; 89 | WORD VerionOfWindows_Socket = MAKEWORD(2, 2); 90 | int res = WSAStartup(VerionOfWindows_Socket, &Windows_Socket_info); 91 | if (res != 0) 92 | { 93 | std::cerr << "INITIALIZE WinSock Error : " << res; 94 | return 0; 95 | } 96 | MySocket = socket(AF_INET, SOCK_STREAM, 0); 97 | if (MySocket == INVALID_SOCKET) 98 | { 99 | std::cerr << "INITIALIZE WinSock Error : " << res; 100 | closesocket(MySocket); 101 | return 0; 102 | } 103 | 104 | My_address.sin_family = AF_INET;//v4 105 | My_address.sin_port = htons(ServerPORT);//6969 106 | int status = inet_pton(AF_INET, ServerIP, &My_address.sin_addr); 107 | if (status <= 0) 108 | { 109 | cerr << "Faild . Error code = " << WSAGetLastError(); 110 | return 0; 111 | } 112 | return 1; 113 | } 114 | void Connection(SOCKET& MySocket, sockaddr_in& My_address) 115 | { 116 | while (true) 117 | { 118 | int status = connect(MySocket, (sockaddr*)&My_address, sizeof(My_address)); 119 | if (status < 0) 120 | cerr << "[Log] :Please Wait Connection Error !\n"; 121 | else 122 | break; 123 | Sleep(2 * 1000); 124 | 125 | } 126 | clog << "[Log] :Connected To Server !\n"; 127 | 128 | } 129 | 130 | bool SendBufferSize(long buffersize) 131 | { 132 | stringstream st; 133 | st << bitset<8 * sizeof(long) >(buffersize); 134 | int status = send(MySocket, st.str().c_str(), 8 * sizeof(long), 0);; 135 | if (status < 0) 136 | { 137 | cerr << "Send Error !\n"; 138 | return 0; 139 | } 140 | clog << "[LOG] : Data Send\n"; 141 | return 1; 142 | } 143 | bool Send(const char * buffer , long buffersize) 144 | { 145 | if (SendBufferSize(buffersize)) 146 | { 147 | int status = send(MySocket, buffer, BUFFERLENGTH, 0); 148 | if (status < 0) 149 | { 150 | cerr << "Send Error !\n"; 151 | return 0; 152 | } 153 | clog << "[LOG] : Data Send\n"; 154 | 155 | return 1; 156 | } 157 | return 0; 158 | } 159 | //struct Header 160 | //{ 161 | // long size; 162 | // string Extention; 163 | // string Filename; 164 | // Type type; 165 | // Json Encode() 166 | // { 167 | // Json json; 168 | // json["size"] = size; 169 | // json["Extention"] = Extention; 170 | // json["Filename"] = Filename; 171 | // json["type"] = type; 172 | // return json; 173 | // } 174 | // void Decode(string input) 175 | // { 176 | // auto json = Json::parse(input);; 177 | // size = json["size"].get(); 178 | // Extention = json["Extention"].get(); 179 | // Filename = json["Filename"].get(); 180 | // type = json["type"].get(); 181 | // } 182 | //}; 183 | 184 | void SendFile(const string& source) 185 | { 186 | char Buffer[BUFFERLENGTH]; 187 | ifstream ifs(source, ios::binary); 188 | long size = ifs.seekg(0, ios::end).tellg(); 189 | ifs.seekg(0, ios::beg); 190 | istreambuf_iterator inputstream(ifs); 191 | long Current = 0; 192 | Json json; 193 | json["size"] = size; 194 | json["Extention"] = GetFileExtention(source); 195 | json["Filename"] = GetFileNameWhitOutExtention(source); 196 | json["type"] = Header::FileInfo; 197 | strcpy(Buffer, json.dump().c_str()); 198 | 199 | Send(Buffer, json.dump().length()); 200 | char License[1]; 201 | char RecievedBufferSize[8 * sizeof(long)]; 202 | long RecievedSize; 203 | int iResult = recv(MySocket, RecievedBufferSize, 8 * sizeof(long), 0); 204 | clog << "[LOG] : recv SendAuthorize Size\n"; 205 | if (iResult > 0) 206 | { 207 | RecievedSize = std::stol(RecievedBufferSize, 0, 2); 208 | clog << "[LOG] : recv SendAuthorize Data\n"; 209 | 210 | if (RecievedSize > 0) 211 | { 212 | recv(MySocket, Buffer, BUFFERLENGTH, 0); 213 | } 214 | } 215 | json = Json::parse(string(Buffer, RecievedSize)); 216 | 217 | Header Head = json["type"].get
(); 218 | clog << "[LOG] : Start File Sending\n"; 219 | if (Header::SendAuthorize == Head) 220 | { 221 | 222 | while (Current < size) 223 | { 224 | long readindex = size - Current < BUFFERLENGTH ? size - Current : BUFFERLENGTH ; 225 | copy_n(inputstream, readindex, Buffer); 226 | ifs.seekg(1, ios::cur); 227 | Current += readindex; 228 | Send(Buffer, readindex); 229 | } 230 | clog << "[LOG] : Finish\n"; 231 | } 232 | ifs.close(); 233 | } 234 | bool Recive(char* buffer, long& buffersize) 235 | { 236 | int status = recv(MySocket, buffer, BUFFERLENGTH, 0); 237 | buffersize = strlen(buffer); 238 | 239 | if (status < 0) { 240 | std::cerr << "abort\n"; 241 | closesocket(MySocket); //clean up 242 | WSACleanup(); //clean up 243 | return 0; 244 | } 245 | } 246 | void ReceiveFile(string path , int size) 247 | { 248 | ofstream ofstmp(path, ios::binary); 249 | ostreambuf_iterator outfile(ofstmp); 250 | char Buffer[BUFFERLENGTH]; 251 | long Current = 0; 252 | while (Current < size) 253 | { 254 | long readindex ; 255 | Recive(Buffer, readindex); 256 | copy_n(Buffer, readindex, outfile); 257 | Current += readindex; 258 | } 259 | ofstmp.close(); 260 | } 261 | int main() 262 | { 263 | if (SocketConfig()) 264 | { 265 | Connection(MySocket, My_address); 266 | string path; 267 | cout << "File Path : (For Example : C:\\Users\\amirr\\Pictures\\Test.png)"; 268 | getline(cin, path); 269 | SendFile(path); 270 | } 271 | closesocket(MySocket); 272 | WSACleanup(); 273 | } 274 | -------------------------------------------------------------------------------- /Server/Clinet.hpp: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------- 2 | // Design Name : Server Side Socket 3 | // File Name : Client.hpp 4 | // Function : Handel Clients 5 | // Coder : Amirreza Tavakoli 6 | //----------------------------------------------------- 7 | #ifndef ClientS_H 8 | #define ClientS_H 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include "Connection.hpp" 14 | #include 15 | #include 16 | #include "FileProccess.hpp" 17 | using namespace std; 18 | using Json = nlohmann::json; 19 | #define BUFFERLENGTH 80 * 1024 20 | enum Header 21 | { 22 | FileInfo, 23 | Message, 24 | File, 25 | SendAuthorize 26 | }; 27 | class Clinets 28 | { 29 | public: 30 | ClientInfo Client; 31 | TCPServer* Server; 32 | WriteRecievedFile* file; 33 | Clinets(TCPServer* server) 34 | { 35 | Server = server; 36 | AcceptConnection(); 37 | } 38 | ~Clinets() 39 | { 40 | delete(Server); 41 | } 42 | private: 43 | void AcceptConnection() 44 | { 45 | auto v = Server->BeginAccepting(); 46 | Client = (v); 47 | char RecievedBufferSize[8 * sizeof(long)]; 48 | std::clog << "[Log]: Client Connected \n"; 49 | BeginRecive(Client.Sock); 50 | } 51 | bool SendBufferSize(long buffersize, SOCKET Client) 52 | { 53 | stringstream st; 54 | st << bitset<8 * sizeof(long)>(buffersize); 55 | int status = send(Client, st.str().c_str(), 8 * sizeof(long), 0);; 56 | if (status < 0) 57 | return 0; 58 | return 1; 59 | } 60 | bool Send(const char* buffer, long buffersize, SOCKET Client) 61 | { 62 | if (SendBufferSize(buffersize , Client)) 63 | { 64 | std::clog << "[Log]: Send Data \n"; 65 | int status = send(Client, buffer, buffersize, 0); 66 | if (status < 0) 67 | return 0; 68 | return 1; 69 | } 70 | return 0; 71 | } 72 | public:void BeginRecive(SOCKET Client) 73 | { 74 | while (true) 75 | { 76 | char tmpbuffer[BUFFERLENGTH]{0}; 77 | char RecievedBufferSize[8 * sizeof(long)]; 78 | int iResult = recv(Client, RecievedBufferSize, 8 * sizeof(long), 0); 79 | if (iResult > 0) 80 | { 81 | long RecievedSize = std::stol(RecievedBufferSize, 0, 2); 82 | 83 | if (RecievedSize > 0) 84 | { 85 | std::clog << "[Log]: Recieved Data \n"; 86 | 87 | recv(Client, tmpbuffer, BUFFERLENGTH, 0); 88 | Proccess(tmpbuffer, RecievedSize); 89 | } 90 | } 91 | } 92 | } 93 | void Proccess(char* buffer ,const long& buffersize) 94 | { 95 | Json json ; 96 | Header Head = Header::File; 97 | try 98 | { 99 | json = Json::parse(string(buffer, buffersize)); 100 | Head = json["type"].get
(); 101 | } 102 | catch (...) 103 | { 104 | // Ignor 105 | } 106 | switch (Head) 107 | { 108 | case Header::FileInfo : 109 | { 110 | string Extention = json["Extention"].get(); 111 | string Filename = json["Filename"].get(); 112 | long size = json["size"].get(); 113 | file = new WriteRecievedFile(Filename, Extention, size); 114 | Json sendjson; 115 | sendjson["type"] = Header::SendAuthorize; 116 | Send(sendjson.dump().c_str(), sizeof(sendjson), Client.Sock); 117 | } 118 | break; 119 | case Header::File: 120 | file->StartWrite(buffer, buffersize); 121 | break; 122 | default: 123 | break; 124 | } 125 | } 126 | }; 127 | #endif // !Client_H 128 | -------------------------------------------------------------------------------- /Server/Connection.hpp: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------- 2 | // Design Name : Server Side Socket 3 | // File Name : Connection.hpp 4 | // Function : Initial Server 5 | // Coder : Amirreza Tavakoli 6 | //----------------------------------------------------- 7 | #ifndef Connection_H 8 | #define Connection_H 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include "json.hpp" 15 | #include 16 | #pragma comment (lib, "Ws2_32.lib") 17 | using std::string; 18 | using std::to_string; 19 | using std::vector; 20 | struct ClientInfo 21 | { 22 | SOCKET Sock ; 23 | string ClientIP; 24 | }; 25 | class TCPServer 26 | { 27 | public: 28 | int PORT; 29 | string IP; 30 | TCPServer(int PORT = 6969 , string ipv4 = "127.0.0.1") 31 | { 32 | WSADATA Windows_Socket_info; 33 | WORD VerionOfWindows_Socket = MAKEWORD(2, 2); 34 | int res = WSAStartup(VerionOfWindows_Socket, &Windows_Socket_info); 35 | if (res != 0) 36 | { 37 | throw "WSAStartup Error " + to_string(res); 38 | } 39 | this->PORT = PORT; 40 | this->IP = ipv4; 41 | CreatSocket(); 42 | std::clog << "[Log]: Server Start On " << ipv4 << " IP Address in " << PORT << " Port \n"; 43 | Listen(); 44 | std::clog << "[Log]: Start Listening \n"; 45 | } 46 | ~TCPServer() 47 | { 48 | WSAGetLastError(); 49 | closesocket(Server_sock); 50 | WSACleanup(); 51 | } 52 | ClientInfo BeginAccepting() 53 | { 54 | SOCKET NewClient_Sock; 55 | char ClientIP[256]; 56 | sockaddr_in client_address; 57 | int client_address_size = sizeof(client_address); 58 | NewClient_Sock = accept(Server_sock, (sockaddr*)&client_address, &client_address_size); 59 | if (NewClient_Sock == INVALID_SOCKET) { 60 | closesocket(NewClient_Sock); //clean up 61 | WSACleanup(); //clean up 62 | } 63 | inet_ntop(AF_INET, &client_address.sin_addr, ClientIP, 256); //NEW 64 | ClientInfo NewClient{ NewClient_Sock , ClientIP }; 65 | return NewClient; 66 | } 67 | private: 68 | SOCKET Server_sock; 69 | bool CreatSocket() 70 | { 71 | sockaddr_in server_address; 72 | server_address.sin_family = AF_INET; 73 | server_address.sin_port = htons(PORT); 74 | server_address.sin_addr.S_un.S_addr = inet_addr(IP.c_str()); 75 | Server_sock = socket(AF_INET, SOCK_STREAM, 0); 76 | int status = ::bind((SOCKET)Server_sock, (sockaddr*)&server_address, sizeof(server_address)); 77 | if (status == SOCKET_ERROR) { 78 | closesocket(Server_sock); 79 | WSACleanup(); 80 | return 0; 81 | } 82 | return 1; 83 | } 84 | bool Listen( int ListenLen = SOMAXCONN) 85 | { 86 | int status = listen(Server_sock, ListenLen); 87 | 88 | if (status == SOCKET_ERROR) { 89 | closesocket(Server_sock); 90 | WSACleanup(); 91 | return 0; 92 | } 93 | return 1; 94 | } 95 | }; 96 | #endif // !Connection_H 97 | -------------------------------------------------------------------------------- /Server/FileProccess.hpp: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------- 2 | // Design Name : Server Side Socket 3 | // File Name : FileProccess.hpp 4 | // Function : Handel Recieved File 5 | // Coder : Amirreza Tavakoli 6 | //----------------------------------------------------- 7 | #ifndef FileProccess 8 | #define FileProccess 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | using namespace std; 15 | class FileHandler 16 | { 17 | public: 18 | static string GetFileName(string path) 19 | { 20 | for (int i = path.length(); i >= 0; i--) 21 | if (path[i] == '\\') 22 | return path.substr(i + 1); 23 | return path; 24 | } 25 | static string GetFileExtention(string path) 26 | { 27 | string filename = GetFileName(path); 28 | size_t i = filename.rfind('.', filename.length()); 29 | if (i != string::npos) { 30 | return(filename.substr(i, filename.length() - i)); 31 | } 32 | } 33 | static string GetFileNameWhitOutExtention(string path) 34 | { 35 | string filename = GetFileName(path); 36 | size_t i = filename.rfind('.', filename.length()); 37 | if (i != string::npos) { 38 | return(filename.substr(0, i)); 39 | } 40 | } 41 | static inline string TempPath(string Filename, string Extention = ".tmp") 42 | { 43 | return Filename + Extention; 44 | } 45 | static inline bool IsFileExist(const string& name) { 46 | ifstream f(name.c_str()); 47 | return f.good(); 48 | } 49 | static bool ConvertTmpToStableFile(const string& tmppath, const string& destinationpath) 50 | { 51 | if (!IsFileExist(tmppath)) 52 | return 0; 53 | if (rename(tmppath.c_str(), destinationpath.c_str()) != 0) 54 | ConvertTmpToStableFile(tmppath, GetFileNameWhitOutExtention(destinationpath) + "_Copy" + GetFileExtention(destinationpath)); 55 | else 56 | return 1; 57 | } 58 | }; 59 | 60 | class WriteRecievedFile 61 | { 62 | public: 63 | string FileExtention; 64 | string FileName; 65 | long TotalSize; 66 | long CurrentPos; 67 | ofstream ofstmp; 68 | WriteRecievedFile(string FileName , string FileExtention, long totalSize) 69 | { 70 | ofstmp.open(FileHandler::TempPath(FileName), ios::binary); 71 | CurrentPos = 0; 72 | TotalSize = totalSize; 73 | this->FileExtention = FileExtention; 74 | this->FileName = FileName; 75 | } 76 | void StartWrite(char* Buffer , long RecievedBufferSize) 77 | { 78 | ofstmp.write(Buffer, RecievedBufferSize); 79 | CurrentPos += RecievedBufferSize; 80 | if (!(CurrentPos < TotalSize)) 81 | { 82 | ofstmp.close(); 83 | FileHandler::ConvertTmpToStableFile(FileHandler::TempPath(FileName), FileName+ FileExtention); 84 | std::clog << "[Log]: Finish Recieving File \n"; 85 | 86 | } 87 | } 88 | }; 89 | 90 | 91 | #endif // !FileProccess 92 | -------------------------------------------------------------------------------- /Server/Main.cpp: -------------------------------------------------------------------------------- 1 | // Add nlohmann json from Nuget 2 | 3 | #define _CRT_SECURE_NO_WARNINGS 4 | #define _WINSOCK_DEPRECATED_NO_WARNINGS 5 | 6 | #include "Clinet.hpp" 7 | 8 | int main() 9 | { 10 | TCPServer server(6969); 11 | Clinets clinte (&server); 12 | } 13 | -------------------------------------------------------------------------------- /SimpleClientSock.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #pragma comment(lib,"ws2_32.lib") //Winsock Library 5 | using namespace std; 6 | 7 | #define ServerPORT 6969 8 | #define ServerIP "127.0.0.1" 9 | #define BUFFERLEN 1 * 1024 10 | 11 | int main(int argc, char* argv[]) 12 | { 13 | // INITIALIZE Win Socket 14 | WSADATA Win_Socket_Info; 15 | SOCKET MyConnection; 16 | 17 | if (WSAStartup(MAKEWORD(2, 2), &Win_Socket_Info) != 0) 18 | { 19 | cerr << "Failed. Error Code : " << WSAGetLastError(); 20 | return 1; 21 | } 22 | cout << "\nInitialised..."; 23 | 24 | // CREATE SOCKET 25 | if ((MyConnection = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) 26 | { 27 | cout << "\nCould not create socket :" << WSAGetLastError(); 28 | WSACleanup(); 29 | } 30 | cout << "\nSocket created..."; 31 | 32 | // FILL IN HINT STRUCTURE 33 | sockaddr_in Server_Info; 34 | Server_Info.sin_family = AF_INET; 35 | Server_Info.sin_port = htons(ServerPORT); 36 | if (inet_pton(AF_INET, ServerIP, &Server_Info.sin_addr) <= 0) 37 | { 38 | cerr << "Failed. Error Code : " << WSAGetLastError(); 39 | WSACleanup(); 40 | return 1; 41 | } 42 | 43 | //CONNECT TO SERVER 44 | while (true) 45 | { 46 | int connectionResult = connect(MyConnection, (struct sockaddr*)&Server_Info, sizeof(Server_Info)); 47 | if (connectionResult == SOCKET_ERROR) 48 | { 49 | cerr << "\nCan not Connect to server ... !"; 50 | } 51 | else 52 | break; 53 | Sleep(2 * 1000); 54 | } 55 | 56 | 57 | cout << "\nConnected\n"; 58 | 59 | //Send some data 60 | char Buffer[BUFFERLEN]; 61 | string MESSAGE; 62 | while (true) 63 | { 64 | cout << "\n-> Write your Message : "; 65 | std::getline(std::cin, MESSAGE); 66 | if (!MESSAGE.empty()) 67 | { 68 | if (send(MyConnection, MESSAGE.c_str() , MESSAGE.length() + 1 , 0) < 0) 69 | { 70 | cerr << ("\nSend failed"); 71 | return 1; 72 | } 73 | ZeroMemory(Buffer, BUFFERLEN); 74 | int byteRecieved = recv(MyConnection, Buffer, BUFFERLEN, 0); 75 | if (byteRecieved > 0) 76 | { 77 | cout << "Server > " << string(Buffer , byteRecieved); 78 | } 79 | 80 | } 81 | } 82 | 83 | return 0; 84 | } 85 | -------------------------------------------------------------------------------- /SimpleSingleClientServerSock.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #pragma comment (lib, "Ws2_32.lib") 8 | #define BUFFERLEN 1 * 1024 9 | #define PORT 6969 10 | using namespace std; 11 | 12 | int main() 13 | { 14 | 15 | //INITIALIZE Win Socket 16 | WSADATA Windows_Socket_info; 17 | WORD VerionOfWindows_Socket = MAKEWORD(2, 2); 18 | int res = WSAStartup(VerionOfWindows_Socket, &Windows_Socket_info); 19 | if (res != 0) 20 | { 21 | std::cerr << "INITIALIZE WinSock Error : " << res; 22 | return 0; 23 | } 24 | 25 | //CREATE LISTENING SOCKET 26 | SOCKET Server_sock = socket(AF_INET, SOCK_STREAM, 0); 27 | if (Server_sock == SOCKET_ERROR) { 28 | std::cerr << "ABORT\n"; 29 | closesocket(Server_sock); //clean up 30 | WSACleanup(); //clean up 31 | return 0; 32 | } 33 | //BIND THE IP ADDRESS AND PORT TO A SOCKET 34 | sockaddr_in server_address; 35 | server_address.sin_family = AF_INET; 36 | server_address.sin_port = htons(PORT); 37 | server_address.sin_addr.S_un.S_addr = INADDR_ANY; // or inet_addr("127.0.0.1"); 38 | 39 | int status = ::bind(Server_sock, (sockaddr*)&server_address, sizeof(server_address)); 40 | 41 | if (status == SOCKET_ERROR) { 42 | std::cerr << "ABORT\n"; 43 | closesocket(Server_sock); //clean up 44 | WSACleanup(); //clean up 45 | return 0; 46 | } 47 | 48 | // TELL WINDSOCK THE SOCKET IS FOE LISTENNING 49 | status = listen(Server_sock, SOMAXCONN); 50 | if (status < 0) { 51 | std::cerr << "ABORT\n"; 52 | closesocket(Server_sock); //clean up 53 | WSACleanup(); //clean up 54 | return 0; 55 | } 56 | 57 | //WAIT FOR CONNECTION 58 | sockaddr_in client_address; 59 | int client_address_size = sizeof(client_address); 60 | 61 | SOCKET NewClient = accept(Server_sock, (sockaddr*)&client_address, &client_address_size); 62 | if (NewClient == INVALID_SOCKET) 63 | { 64 | std::cerr << "ABORT\n"; 65 | closesocket(NewClient); //clean up 66 | WSACleanup(); //clean up 67 | } 68 | 69 | char Host[NI_MAXHOST]; 70 | char Service[NI_MAXSERV]; 71 | 72 | ZeroMemory(Host , NI_MAXHOST); // memset(clientip , 0 , NI_MAXHOST); 73 | ZeroMemory(Service, NI_MAXSERV); 74 | 75 | if (getnameinfo((sockaddr*)&client_address, sizeof(client_address), Host, NI_MAXHOST, Service, NI_MAXSERV , 0) == 0 ) 76 | { 77 | cout << Host << "Connected on port " << Service; 78 | } 79 | else 80 | { 81 | inet_ntop(AF_INET, &client_address.sin_addr, Host, NI_MAXHOST); 82 | cout << Host << "Connected on port " << ntohs(client_address.sin_port); 83 | } 84 | char buffer[BUFFERLEN]; 85 | //RECEIVE MESSAGE 86 | while (true) 87 | { 88 | ZeroMemory(buffer, BUFFERLEN); 89 | int ByteRecieved = recv(NewClient, buffer, sizeof(buffer), 0); 90 | if (ByteRecieved == SOCKET_ERROR) { 91 | std::cout << "Error in Recv()\n"; 92 | closesocket(NewClient); //clean up 93 | WSACleanup(); //clean up 94 | return 0; 95 | } 96 | if (ByteRecieved == 0) 97 | { 98 | std::cout << "Client Disconnected\n"; 99 | closesocket(NewClient); //clean up 100 | WSACleanup(); //clean up 101 | return 0; 102 | } 103 | std::cerr << Host << ": " << buffer << std::endl; 104 | string message; 105 | cin >> message; 106 | send(NewClient, message.c_str(), message.length() + 1, 0); 107 | } 108 | 109 | WSAGetLastError(); 110 | 111 | system("pause"); 112 | closesocket(Server_sock); 113 | WSACleanup(); 114 | 115 | } 116 | -------------------------------------------------------------------------------- /SimpleSingleThreadMultiClientServer.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #pragma comment (lib, "Ws2_32.lib") 8 | #define BUFFERLEN 1 * 1024 9 | #define PORT 6969 10 | using namespace std; 11 | 12 | int main() 13 | { 14 | 15 | //INITIALIZE Win Socket 16 | WSADATA Windows_Socket_info; 17 | WORD VerionOfWindows_Socket = MAKEWORD(2, 2); 18 | int res = WSAStartup(VerionOfWindows_Socket, &Windows_Socket_info); 19 | if (res != 0) 20 | { 21 | std::cerr << "INITIALIZE WinSock Error : " << res; 22 | return 0; 23 | } 24 | 25 | //CREATE LISTENING SOCKET 26 | SOCKET Server_sock = socket(AF_INET, SOCK_STREAM, 0); 27 | if (Server_sock == SOCKET_ERROR) { 28 | std::cerr << "ABORT\n"; 29 | closesocket(Server_sock); //clean up 30 | WSACleanup(); //clean up 31 | return 0; 32 | } 33 | //BIND THE IP ADDRESS AND PORT TO A SOCKET 34 | sockaddr_in server_address; 35 | server_address.sin_family = AF_INET; 36 | server_address.sin_port = htons(PORT); 37 | server_address.sin_addr.S_un.S_addr = INADDR_ANY; // or inet_addr("127.0.0.1"); 38 | 39 | int status = ::bind(Server_sock, (sockaddr*)&server_address, sizeof(server_address)); 40 | 41 | if (status == SOCKET_ERROR) { 42 | std::cerr << "ABORT\n"; 43 | closesocket(Server_sock); //clean up 44 | WSACleanup(); //clean up 45 | return 0; 46 | } 47 | 48 | // TELL WINDSOCK THE SOCKET IS FOE LISTENNING 49 | status = listen(Server_sock, SOMAXCONN); 50 | if (status < 0) { 51 | std::cerr << "ABORT\n"; 52 | closesocket(Server_sock); //clean up 53 | WSACleanup(); //clean up 54 | return 0; 55 | } 56 | 57 | 58 | fd_set master; 59 | FD_ZERO(&master); 60 | FD_SET(Server_sock, &master); 61 | 62 | 63 | //WAIT FOR CONNECTION 64 | while (true) 65 | { 66 | fd_set Read = master; 67 | 68 | int socketcount = select(0, &Read, nullptr, nullptr, nullptr); 69 | 70 | for (int i = 0; i < Read.fd_count; i++) 71 | { 72 | SOCKET sock = Read.fd_array[i]; 73 | if (sock == Server_sock) // Accetp a new connection 74 | { 75 | 76 | sockaddr_in client_address; 77 | int client_address_size = sizeof(client_address); 78 | 79 | SOCKET NewClient = accept(Server_sock, (sockaddr*)&client_address, &client_address_size); 80 | if (NewClient == INVALID_SOCKET) 81 | { 82 | std::cerr << "ABORT\n"; 83 | closesocket(NewClient); //clean up 84 | WSACleanup(); //clean up 85 | } 86 | 87 | char Host[NI_MAXHOST]; 88 | char Service[NI_MAXSERV]; 89 | 90 | ZeroMemory(Host, NI_MAXHOST); // memset(clientip , 0 , NI_MAXHOST); 91 | ZeroMemory(Service, NI_MAXSERV); 92 | 93 | if (getnameinfo((sockaddr*)&client_address, sizeof(client_address), Host, NI_MAXHOST, Service, NI_MAXSERV, 0) == 0) 94 | { 95 | cout << Host << "Connected on port " << Service << endl; 96 | } 97 | else 98 | { 99 | inet_ntop(AF_INET, &client_address.sin_addr, Host, NI_MAXHOST); 100 | cout << Host << "Connected on port " << ntohs(client_address.sin_port) << endl; 101 | } 102 | char buffer[BUFFERLEN]; 103 | 104 | 105 | // Add the new connection to list of connected client 106 | FD_SET(NewClient, &master); 107 | } 108 | else// Accept a new massage 109 | { 110 | char buf[4096]; 111 | ZeroMemory(buf, 4096); 112 | int bytesIn = recv(sock, buf, 4096, 0); 113 | if (bytesIn <= 0) 114 | { 115 | closesocket(sock); 116 | FD_CLR(sock, &master); 117 | } 118 | else 119 | { 120 | string str(buf, bytesIn); 121 | cout << str; 122 | send(sock, str.c_str(), str.size()+1,0); // Echo Message To Client 123 | } 124 | } 125 | } 126 | 127 | } 128 | 129 | WSAGetLastError(); 130 | 131 | system("pause"); 132 | closesocket(Server_sock); 133 | WSACleanup(); 134 | 135 | } 136 | -------------------------------------------------------------------------------- /TCP/Client/ClientConnection.cpp: -------------------------------------------------------------------------------- 1 | #include "ClientConnection.h" 2 | ClientConnection::ClientConnection() 3 | { 4 | 5 | } 6 | ClientConnection::ClientConnection(string ip, int port, MessageRecieverHandler mrh , Accept_Handler ah) 7 | : Serverip(ip) , Serverport(port) , RecieverHandler (mrh) , AcceptHandler(ah) 8 | { 9 | 10 | 11 | } 12 | ClientConnection::~ClientConnection() 13 | { 14 | Cleanup(); 15 | } 16 | bool ClientConnection::Init() 17 | { 18 | WSADATA windows_Socket_info; 19 | WORD version = MAKEWORD(2, 2); 20 | int res = WSAStartup(version, &windows_Socket_info); 21 | return res == 0; 22 | } 23 | void ClientConnection::Start() 24 | { 25 | ClientConnection::MySock = CreatSocket(); 26 | if (MySock != INVALID_SOCKET) 27 | { 28 | Run(); 29 | } 30 | } 31 | void ClientConnection::Send(const char* buffer, int Length) 32 | { 33 | send(MySock, buffer, Length, 0); 34 | } 35 | void ClientConnection::Run() 36 | { 37 | thread NEWRecievedTH; 38 | int bytesIN = recv(MySock, BUFFER, BUFFER_SIZE, 0); 39 | if (bytesIN <= 0) 40 | { 41 | closesocket(MySock); 42 | return; 43 | } 44 | else 45 | { 46 | if (bytesIN >= 1) 47 | NEWRecievedTH = thread([&]() {RecieverHandler(MySock, BUFFER, bytesIN); }); 48 | } 49 | Run(); 50 | NEWRecievedTH.join(); 51 | } 52 | void ClientConnection::Cleanup() 53 | { 54 | ClientConnection::IsRunning = false; 55 | closesocket(ClientConnection::MySock); 56 | WSACleanup(); 57 | } 58 | SOCKET ClientConnection::CreatSocket() 59 | { 60 | SOCKET MySocket = socket(AF_INET, SOCK_STREAM, 0); 61 | if (MySocket != INVALID_SOCKET) 62 | { 63 | sockaddr_in Server_Info; 64 | Server_Info.sin_family = AF_INET; 65 | Server_Info.sin_port = htons(Serverport); 66 | if (inet_pton(AF_INET, Serverip.c_str(), &Server_Info.sin_addr) <= 0) 67 | { 68 | Cleanup(); 69 | return -1; 70 | } 71 | //CONNECT TO SERVER 72 | int connectionResult = connect(MySocket, ( sockaddr*)&Server_Info, sizeof(Server_Info)); 73 | 74 | if (connectionResult == SOCKET_ERROR) 75 | { 76 | Cleanup(); 77 | return -1; 78 | } 79 | AcceptHandler(MySocket); 80 | IsRunning = true; 81 | return MySocket; 82 | } 83 | else 84 | { 85 | Cleanup(); 86 | return -1; 87 | } 88 | } -------------------------------------------------------------------------------- /TCP/Client/ClientConnection.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #ifndef TCPLISTENER_H 3 | #define TCPLISTENER_H 4 | #include 5 | #pragma comment (lib , "Ws2_32.lib") 6 | #include 7 | #include "PACKET.h" 8 | #include 9 | using std::string; 10 | using std::thread; 11 | 12 | typedef void (*Accept_Handler)(int socketid); 13 | typedef void (*MessageRecieverHandler)(int socketid , char* buffer , const int& datalength); 14 | 15 | class ClientConnection 16 | { 17 | public: 18 | ClientConnection(); 19 | ClientConnection(string ip, int port, MessageRecieverHandler , Accept_Handler); 20 | ~ClientConnection(); 21 | bool Init(); 22 | void Start(); 23 | void Send(const char* buffer , int Length); 24 | bool IsRunning = false; 25 | private : 26 | void Run(); 27 | SOCKET CreatSocket(); 28 | void Cleanup(); 29 | char BUFFER[BUFFER_SIZE]; 30 | MessageRecieverHandler RecieverHandler; 31 | Accept_Handler AcceptHandler; 32 | string Serverip; 33 | int Serverport; 34 | SOCKET MySock; 35 | }; 36 | 37 | #endif // !TCPLISTENER_H 38 | 39 | -------------------------------------------------------------------------------- /TCP/Client/FileHandler.h: -------------------------------------------------------------------------------- 1 | #ifndef FILEHANDLER_H 2 | #define FILEHANDLER_H 3 | #include 4 | #include 5 | using std::string; 6 | using std::ifstream; 7 | class FileHandler 8 | { 9 | public: 10 | static string GetFileName(string path) 11 | { 12 | for (int i = path.length(); i >= 0; i--) 13 | if (path[i] == '\\') 14 | return path.substr(i + 1); 15 | return path; 16 | } 17 | static string GetFileExtention(string path) 18 | { 19 | string filename = GetFileName(path); 20 | size_t i = filename.rfind('.', filename.length()); 21 | if (i != string::npos) { 22 | return(filename.substr(i, filename.length() - i)); 23 | } 24 | } 25 | static string GetFileNameWhitOutExtention(string path) 26 | { 27 | string filename = GetFileName(path); 28 | size_t i = filename.rfind('.', filename.length()); 29 | if (i != string::npos) { 30 | return(filename.substr(0, i)); 31 | } 32 | } 33 | static inline string Combine(string str1 , string str2) 34 | { 35 | return str1 + "\\" + str2; 36 | } 37 | static inline string TempPath(string Filename, string Extention = ".tmp") 38 | { 39 | return Filename + Extention; 40 | } 41 | static inline bool IsFileExist(const string& name) { 42 | ifstream f(name.c_str()); 43 | return f.good(); 44 | } 45 | static bool ConvertTmpToStableFile(const string& tmppath, const string& destinationpath) 46 | { 47 | if (!IsFileExist(tmppath)) 48 | return 0; 49 | if (rename(tmppath.c_str(), destinationpath.c_str()) != 0) 50 | ConvertTmpToStableFile(tmppath, GetFileNameWhitOutExtention(destinationpath) + "_Copy" + GetFileExtention(destinationpath)); 51 | else 52 | return 1; 53 | } 54 | }; 55 | #endif 56 | 57 | 58 | -------------------------------------------------------------------------------- /TCP/Client/PACKET.cpp: -------------------------------------------------------------------------------- 1 | #include "PACKET.h" 2 | -------------------------------------------------------------------------------- /TCP/Client/PACKET.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #ifndef PACKET_H 3 | #define PACKET_H 4 | #define BUFFER_SIZE 8 * 1024 5 | #define StartQueuePacket_SIZE BUFFER_SIZE - 165 - 205 - sizeof(long) - 4 6 | #define FilePacket_SIZE BUFFER_SIZE - 3 * sizeof(int) 7 | #define MeasgePacket_SIZE BUFFER_SIZE - 4 8 | enum Header : char 9 | { 10 | queue, 11 | Start, 12 | Stop, 13 | Chunck, 14 | Message, 15 | HeartBit 16 | }; // 17 | struct PACKET 18 | { 19 | Header head; 20 | }; 21 | struct StartQueuePacket : public PACKET // Queue 22 | { 23 | char FileName[165]; 24 | char FileExtention[205]; 25 | long Size; 26 | int QueueID; 27 | }; 28 | struct FilePacket : public PACKET // Chunck 29 | { 30 | int QueueID; 31 | int Index; 32 | int Read; 33 | char *Buffer; // 8180 34 | }; 35 | struct MeasgePacket : public PACKET // Message 36 | { 37 | int size; 38 | char Buffer[MeasgePacket_SIZE]; 39 | }; 40 | #endif // !PACKET_H 41 | 42 | -------------------------------------------------------------------------------- /TCP/Client/Queue.cpp: -------------------------------------------------------------------------------- 1 | #include "Queue.h" 2 | ClientConnection* Queue::myConnection = nullptr; 3 | 4 | Queue* Queue::UploadQueue(std::string FilePath) 5 | { 6 | try 7 | { 8 | auto queue = new Queue(); 9 | queue->FileName = FileHandler::GetFileNameWhitOutExtention(FilePath); 10 | queue->FileExtention = FileHandler::GetFileExtention(FilePath); 11 | queue->Type = QUEUETYPE::Upload; 12 | queue->readfile = std::ifstream(FilePath, std::ios::binary); 13 | if (!queue->readfile) 14 | throw string("File Can not Open!"); 15 | queue->Length = queue->readfile.seekg(0, std::ios::end).tellg(); 16 | queue->Index = 0; 17 | queue->QueueID = rand() % 9000 + 1000; 18 | queue->Trasnfered = 0; 19 | return queue; 20 | } 21 | catch (...) 22 | { 23 | return nullptr; 24 | } 25 | } 26 | Queue* Queue::DownloadQueue(std::string FileName, std::string FileExtention, long Size, int QueuID) 27 | { 28 | try 29 | { 30 | auto queue = new Queue(); 31 | queue->FileName = FileName; 32 | queue->FileExtention = FileExtention; 33 | queue->FilePath = FileHandler::Combine(".",FileHandler::TempPath(FileName)); 34 | queue->Type = QUEUETYPE::Download; 35 | queue->writefile = std::ofstream(queue->FilePath , std::ios::binary); 36 | if (queue->writefile) 37 | throw std::string("Error"); 38 | queue->Length = Size; 39 | queue->QueueID = QueuID; 40 | queue->Trasnfered = 0; 41 | return queue; 42 | } 43 | catch (...) 44 | { 45 | return nullptr; 46 | } 47 | } 48 | void Queue::Start() 49 | { 50 | this->Runnig = true; 51 | this->SendThread = std::thread( [&](){TransferProc(this); }); 52 | } 53 | void Queue::Close() 54 | { 55 | 56 | } 57 | void Queue::Write(const char const* bytes, long readsize) 58 | { 59 | std::lock_guardguard (RecieveDOOR); 60 | this->writefile.write(bytes, readsize); 61 | this->Trasnfered += readsize; 62 | } 63 | void Queue::TransferProc(Queue *queue) 64 | { 65 | while (queue->Runnig && queue->Index < queue->Length) 66 | { 67 | if (myConnection == NULL) 68 | throw string("Connection Error"); 69 | SendDOOR.lock(); 70 | memset(queue->buffer, 0, FilePacket_SIZE); 71 | if (!queue->Runnig) break; 72 | 73 | long read = (queue->Length - queue->Index) < FilePacket_SIZE ? (queue->Length - queue->Index) : FilePacket_SIZE; 74 | 75 | queue->readfile.read(queue->buffer, read); 76 | 77 | FilePacket fp; 78 | fp.head = Header::Chunck; 79 | fp.QueueID = queue->QueueID; 80 | fp.Buffer = queue->buffer; 81 | fp.Read = read; 82 | char Buufer[sizeof(fp)]; 83 | 84 | Serialize::serialize( Buufer , fp); 85 | Queue::myConnection->Send(Buufer , sizeof(fp)); 86 | queue->Index += read; 87 | 88 | queue->Trasnfered += read; 89 | queue->Progress = (int)((queue->Trasnfered * 100) / queue->Length); 90 | if (queue->LastProgress < queue->Progress) 91 | { 92 | queue->LastProgress = queue->Progress; 93 | } 94 | SendDOOR.unlock(); 95 | std::this_thread::sleep_for(std::chrono::milliseconds(1)); 96 | } 97 | queue->Close(); 98 | } 99 | Queue::Queue() 100 | { 101 | myConnection = NULL; 102 | } -------------------------------------------------------------------------------- /TCP/Client/Queue.h: -------------------------------------------------------------------------------- 1 | #ifndef QUEUE_H 2 | #define QUEUE_H 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "PACKET.h" 8 | #include "FileHandler.h" 9 | #include "ClientConnection.h" 10 | #include "Serialize.h" 11 | 12 | enum QUEUETYPE 13 | { 14 | Download, 15 | Upload 16 | }; 17 | class Queue 18 | { 19 | private: 20 | Queue(); 21 | void TransferProc(Queue*); // For Upload 22 | int QueueID; 23 | std::string FilePath; 24 | std::string FileName; 25 | std::string FileExtention; 26 | std::thread SendThread; 27 | 28 | std::mutex SendDOOR; 29 | std::mutex RecieveDOOR; 30 | 31 | std::ifstream readfile; 32 | std::ofstream writefile; 33 | 34 | bool Runnig; 35 | 36 | 37 | char buffer[FilePacket_SIZE]; 38 | public: 39 | static ClientConnection* myConnection; 40 | long Trasnfered; 41 | long Index; 42 | int Progress, LastProgress; 43 | long Length; 44 | QUEUETYPE Type; 45 | 46 | static Queue* UploadQueue( std::string FilePath); 47 | static Queue* DownloadQueue(std::string FileName , std::string FileExtention , long Size , int QueuID); 48 | 49 | void Start(); 50 | void Close(); 51 | void Write(const char const* bytes, long size); // For Downlaod 52 | }; 53 | #endif 54 | -------------------------------------------------------------------------------- /TCP/Client/Serialize.h: -------------------------------------------------------------------------------- 1 | #ifndef SERIALZE_H 2 | #define SERIALZE 3 | #include 4 | template 5 | class Serialize 6 | { 7 | public: 8 | static size_t serialize_Size(const Type input) 9 | { 10 | return sizeof(input); 11 | } 12 | static int serialize(char* const buffer, Type input) 13 | { 14 | memcpy(buffer, &input, sizeof(Type)); 15 | return serialize_Size(input); 16 | } 17 | static int deSerialize(char* buffer, Type& Output) 18 | { 19 | memcpy(&Output, buffer, sizeof(Type)); 20 | return serialize_Size(Output); 21 | } 22 | }; 23 | #endif // !SERIALZE_H 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /TCP/Client/Source.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "ClientConnection.h" 3 | #include "Queue.h" 4 | #include "PACKET.h" 5 | void Accept(int socketid) 6 | { 7 | char Host[NI_MAXHOST]; 8 | char Service[NI_MAXSERV]; 9 | //std::cout << "Accept" << std::endl; 10 | } 11 | void Recieve(int socketid, const char* const buffer, const int& datalength) 12 | { 13 | 14 | string Message = string(buffer, datalength); 15 | //std::cout << "Recieve : " << Message << std::endl; 16 | TCPListener::Send(socketid,Message.c_str(),Message.size()+1); 17 | } 18 | int main() 19 | { 20 | ClientConnection myConnection = ClientConnection("127.0.0.1",7071,Recieve,Accept) ; 21 | Queue::myConnection = &myConnection; 22 | if (myConnection.Init()) 23 | { 24 | 25 | thread th([&](){myConnection.Start();}); 26 | 27 | th.join(); 28 | 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /TCP/Server/Client.h: -------------------------------------------------------------------------------- 1 | #ifndef CLIENT_H 2 | #define CLIENT 3 | struct Client 4 | { 5 | int SocketID; 6 | }; 7 | #endif // !CLIENT_H\ 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /TCP/Server/FileHandler.h: -------------------------------------------------------------------------------- 1 | #ifndef FILEHANDLER_H 2 | #define FILEHANDLER_H 3 | #include 4 | #include 5 | using std::string; 6 | using std::ifstream; 7 | class FileHandler 8 | { 9 | public: 10 | static string GetFileName(string path) 11 | { 12 | for (int i = path.length(); i >= 0; i--) 13 | if (path[i] == '\\') 14 | return path.substr(i + 1); 15 | return path; 16 | } 17 | static string GetFileExtention(string path) 18 | { 19 | string filename = GetFileName(path); 20 | size_t i = filename.rfind('.', filename.length()); 21 | if (i != string::npos) { 22 | return(filename.substr(i, filename.length() - i)); 23 | } 24 | } 25 | static string GetFileNameWhitOutExtention(string path) 26 | { 27 | string filename = GetFileName(path); 28 | size_t i = filename.rfind('.', filename.length()); 29 | if (i != string::npos) { 30 | return(filename.substr(0, i)); 31 | } 32 | } 33 | static inline string Combine(string str1 , string str2) 34 | { 35 | return str1 + "\\" + str2; 36 | } 37 | static inline string TempPath(string Filename, string Extention = ".tmp") 38 | { 39 | return Filename + Extention; 40 | } 41 | static inline bool IsFileExist(const string& name) { 42 | ifstream f(name.c_str()); 43 | return f.good(); 44 | } 45 | static bool ConvertTmpToStableFile(const string& tmppath, const string& destinationpath) 46 | { 47 | if (!IsFileExist(tmppath)) 48 | return 0; 49 | if (rename(tmppath.c_str(), destinationpath.c_str()) != 0) 50 | ConvertTmpToStableFile(tmppath, GetFileNameWhitOutExtention(destinationpath) + "_Copy" + GetFileExtention(destinationpath)); 51 | else 52 | return 1; 53 | } 54 | }; 55 | #endif 56 | 57 | 58 | -------------------------------------------------------------------------------- /TCP/Server/PACKET.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #ifndef PACKET_H 3 | #define PACKET_H 4 | #define SIZE_BUFFER 8 * 1024 //8192 5 | #define SIZE_StartQueuePacket sizeof(StartQueuePacket) //380 6 | #define SIZE_FilePacket SIZE_BUFFER-4*sizeof(int)-1 //8192 7 | #define SIZE_MeasgePacket (SIZE_BUFFER-2*sizeof(int)-1)//8192 8 | 9 | enum Header : char 10 | { 11 | queue, 12 | Start, 13 | Stop, 14 | Chunck, 15 | Message, 16 | HeartBit 17 | }; // 18 | struct PACKET 19 | { 20 | Header head; 21 | }; 22 | struct StartQueuePacket : public PACKET // Queue 23 | { 24 | char FileName[165]; 25 | char FileExtention[205]; 26 | long Size; 27 | int QueueID; 28 | }; 29 | struct FilePacket : public PACKET // Chunck 30 | { 31 | int QueueID; 32 | int Index; 33 | int Read; 34 | char *Buffer; // 8180 35 | }; 36 | struct MeasgePacket : public PACKET // Message 37 | { 38 | int size; 39 | char Buffer[SIZE_MeasgePacket]; 40 | }; 41 | #endif // !PACKET_H 42 | 43 | -------------------------------------------------------------------------------- /TCP/Server/Queue.cpp: -------------------------------------------------------------------------------- 1 | #include "Queue.h" 2 | #include "FileHandler.h" 3 | #include "TCPListener.h" 4 | #include "Serialize.h" 5 | Queue* Queue::UploadQueue(Client* client, std::string FilePath) 6 | { 7 | try 8 | { 9 | auto queue = new Queue(); 10 | queue->client = client; 11 | queue->FileName = FileHandler::GetFileNameWhitOutExtention(FilePath); 12 | queue->FileExtention = FileHandler::GetFileExtention(FilePath); 13 | queue->Type = QUEUETYPE::Upload; 14 | queue->readfile = std::ifstream(FilePath, std::ios::binary); 15 | if (!queue->readfile) 16 | throw string("File Can not Open!"); 17 | queue->Length = queue->readfile.seekg(0, std::ios::end).tellg(); 18 | queue->Index = 0; 19 | queue->QueueID = rand() % 9000 + 1000; 20 | queue->Trasnfered = 0; 21 | return queue; 22 | } 23 | catch (...) 24 | { 25 | return nullptr; 26 | } 27 | } 28 | Queue* Queue::DownloadQueue(std::string FileName, std::string FileExtention, long Size, int QueuID) 29 | { 30 | try 31 | { 32 | auto queue = new Queue(); 33 | queue->FileName = FileName; 34 | queue->FileExtention = FileExtention; 35 | queue->FilePath = FileHandler::Combine(".",FileHandler::TempPath(FileName)); 36 | queue->Type = QUEUETYPE::Download; 37 | queue->writefile = std::ofstream(queue->FilePath , std::ios::binary); 38 | if (queue->writefile) 39 | throw std::string("Error"); 40 | queue->Length = Size; 41 | queue->QueueID = QueuID; 42 | queue->Trasnfered = 0; 43 | return queue; 44 | } 45 | catch (...) 46 | { 47 | return nullptr; 48 | } 49 | } 50 | void Queue::Start() 51 | { 52 | this->Runnig = true; 53 | this->SendThread = std::thread( [&](){TransferProc(this); }); 54 | } 55 | void Queue::Close() 56 | { 57 | 58 | } 59 | void Queue::Write(const char const* bytes, long readsize) 60 | { 61 | std::lock_guardguard (RecieveDOOR); 62 | this->writefile.write(bytes, readsize); 63 | this->Trasnfered += readsize; 64 | } 65 | void Queue::TransferProc(Queue *queue) 66 | { 67 | while (queue->Runnig && queue->Index < queue->Length) 68 | { 69 | SendDOOR.lock(); 70 | memset(queue->buffer, 0, SIZE_FilePacket); 71 | if (!queue->Runnig) break; 72 | 73 | long read = (queue->Length - queue->Index) < SIZE_FilePacket ? (queue->Length - queue->Index) : SIZE_FilePacket; 74 | 75 | queue->readfile.read(queue->buffer, read); 76 | 77 | FilePacket fp; 78 | fp.head = Header::Chunck; 79 | fp.QueueID = queue->QueueID; 80 | fp.Buffer = queue->buffer; 81 | fp.Read = read; 82 | 83 | char Buufer[SIZE_BUFFER]; 84 | memset(queue->buffer, 0, SIZE_BUFFER); 85 | Serialize::serialize(Buufer, fp); 86 | TCPListener::Send(queue->client->SocketID , Buufer , sizeof(fp)); 87 | 88 | queue->Index += read; 89 | 90 | queue->Trasnfered += read; 91 | queue->Progress = (int)((queue->Trasnfered * 100) / queue->Length); 92 | if (queue->LastProgress < queue->Progress) 93 | { 94 | queue->LastProgress = queue->Progress; 95 | } 96 | SendDOOR.unlock(); 97 | std::this_thread::sleep_for(std::chrono::milliseconds(1)); 98 | } 99 | queue->Close(); 100 | } 101 | Queue::Queue() 102 | { 103 | 104 | } -------------------------------------------------------------------------------- /TCP/Server/Queue.h: -------------------------------------------------------------------------------- 1 | #ifndef QUEUE_H 2 | #define QUEUE_H 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "Client.h" 8 | #include "PACKET.h" 9 | enum QUEUETYPE 10 | { 11 | Download, 12 | Upload 13 | }; 14 | class Queue 15 | { 16 | private: 17 | Queue(); 18 | void TransferProc(Queue*); // For Upload 19 | int QueueID; 20 | std::string FilePath; 21 | std::string FileName; 22 | std::string FileExtention; 23 | std::thread SendThread; 24 | 25 | std::mutex SendDOOR; 26 | std::mutex RecieveDOOR; 27 | 28 | std::ifstream readfile; 29 | std::ofstream writefile; 30 | 31 | bool Runnig; 32 | 33 | Client* client; 34 | 35 | char buffer[SIZE_FilePacket]; 36 | public: 37 | long Trasnfered; 38 | long Index; 39 | int Progress, LastProgress; 40 | long Length; 41 | QUEUETYPE Type; 42 | 43 | static Queue* UploadQueue(Client* client , std::string FilePath); 44 | static Queue* DownloadQueue(std::string FileName , std::string FileExtention , long Size , int QueuID); 45 | 46 | void Start(); 47 | void Close(); 48 | void Write(const char const* bytes, long size); // For Downlaod 49 | }; 50 | #endif 51 | -------------------------------------------------------------------------------- /TCP/Server/Serialize.h: -------------------------------------------------------------------------------- 1 | #ifndef SERIALZE_H 2 | #define SERIALZE 3 | #include 4 | template 5 | class Serialize 6 | { 7 | public: 8 | static size_t serialize_Size(const Type input) 9 | { 10 | return sizeof(input); 11 | } 12 | static int serialize(char* const buffer, Type input) 13 | { 14 | memcpy(buffer, &input, sizeof(input)); 15 | return serialize_Size(input); 16 | } 17 | static int deSerialize( char* buffer, Type& Output) 18 | { 19 | memcpy(&Output, buffer, sizeof(Output)); 20 | return serialize_Size(Output); 21 | } 22 | }; 23 | #endif // !SERIALZE_H 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /TCP/Server/TCPListener.cpp: -------------------------------------------------------------------------------- 1 | #include "TCPListener.h" 2 | TCPListener::TCPListener() 3 | { 4 | 5 | } 6 | TCPListener::TCPListener(string ip, int port, MessageRecieverHandler mrh , Accept_Handler ah) 7 | : ip(ip) , port(port) , RecieverHandler (mrh) , AcceptHandler(ah) 8 | { 9 | 10 | 11 | } 12 | TCPListener::~TCPListener() 13 | { 14 | Cleanup(); 15 | } 16 | bool TCPListener::Init() 17 | { 18 | WSADATA windows_Socket_info; 19 | WORD version = MAKEWORD(2, 2); 20 | int res = WSAStartup(version, &windows_Socket_info); 21 | return res == 0; 22 | } 23 | void TCPListener::Start() 24 | { 25 | TCPListener::Server = CreatSocket(); 26 | if (Server != INVALID_SOCKET) 27 | { 28 | FD_SET(Server, &master); 29 | Read = master; 30 | Run(); 31 | } 32 | } 33 | void TCPListener::Send(SOCKET client, const char* buffer, int Length) 34 | { 35 | send(client, buffer, Length, 0); 36 | } 37 | void TCPListener::Run() 38 | { 39 | Read = master; 40 | int SocketCount = select(0, &Read, nullptr, nullptr , nullptr); 41 | thread NewConnectionTH; 42 | thread NEWRecievedTH; 43 | // proccess Socket 44 | if (SocketCount == -1) throw string("Server Connection Fialed!"); 45 | for (int i = 0; i < SocketCount; i++) 46 | { 47 | SOCKET selectedSocket = Read.fd_array[i]; 48 | if (selectedSocket == Server) // Accetp a new connection 49 | { 50 | SOCKET clinet = accept(Server , nullptr , nullptr); 51 | FD_SET(clinet, &master); 52 | NEWRecievedTH = thread([&]() { AcceptHandler(clinet); }); 53 | } 54 | else 55 | { 56 | memset (BUFFER , 0 , SIZE_BUFFER); // ZeroMemory(BUFFER, BUFFER_SIZE); 57 | int bytesIN = recv(selectedSocket , BUFFER , SIZE_BUFFER , 0); 58 | if (bytesIN <= 0) 59 | { 60 | closesocket(selectedSocket); 61 | FD_CLR(selectedSocket , &master); 62 | } 63 | else 64 | { 65 | if(bytesIN >= 1) 66 | NEWRecievedTH = thread([&]() {RecieverHandler(selectedSocket, BUFFER , bytesIN ); }); 67 | 68 | } 69 | } 70 | } 71 | if (IsRunning) 72 | { 73 | Run(); 74 | } 75 | NewConnectionTH.join(); 76 | NEWRecievedTH.join(); 77 | } 78 | void TCPListener::Cleanup() 79 | { 80 | TCPListener::IsRunning = false; 81 | closesocket(TCPListener::Server); 82 | WSACleanup(); 83 | } 84 | SOCKET TCPListener::CreatSocket() 85 | { 86 | SOCKET serversock = socket(AF_INET, SOCK_STREAM, 0); 87 | if (serversock != INVALID_SOCKET) 88 | { 89 | sockaddr_in serveradders; 90 | serveradders.sin_family = AF_INET; 91 | serveradders.sin_port = htons(port); 92 | serveradders.sin_addr.S_un.S_addr = INADDR_ANY;// inet_pton(AF_INET, ip.c_str(), NULL); 93 | int status = ::bind(serversock , (sockaddr*)&serveradders ,sizeof(serveradders)); 94 | if (status != SOCKET_ERROR) 95 | { 96 | status = listen(serversock , SOMAXCONN); 97 | if (status == SOCKET_ERROR) 98 | { 99 | Cleanup(); 100 | return -1; 101 | } 102 | } 103 | else 104 | { 105 | 106 | return -1; 107 | } 108 | IsRunning = true; 109 | return serversock; 110 | } 111 | else 112 | { 113 | Cleanup(); 114 | return -1; 115 | } 116 | } -------------------------------------------------------------------------------- /TCP/Server/TCPListener.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #ifndef TCPLISTENER_H 3 | #define TCPLISTENER_H 4 | #include 5 | #pragma comment (lib , "Ws2_32.lib") 6 | #include 7 | #include "PACKET.h" 8 | #include 9 | using std::string; 10 | using std::thread; 11 | 12 | typedef void (*Accept_Handler)(int socketid); 13 | typedef void (*MessageRecieverHandler)(int socketid , const char* const buffer , const int& datalength); 14 | 15 | class TCPListener 16 | { 17 | public: 18 | TCPListener(); 19 | TCPListener(string ip, int port, MessageRecieverHandler , Accept_Handler); 20 | ~TCPListener(); 21 | bool Init(); 22 | void Start(); 23 | static void Send(SOCKET client ,const char* buffer , int Length); 24 | bool IsRunning = false; 25 | private : 26 | void Run(); 27 | SOCKET CreatSocket(); 28 | fd_set master; 29 | fd_set Read; 30 | void Cleanup(); 31 | char BUFFER[SIZE_BUFFER]; 32 | MessageRecieverHandler RecieverHandler; 33 | Accept_Handler AcceptHandler; 34 | string ip; 35 | int port; 36 | SOCKET Server; 37 | }; 38 | 39 | #endif // !TCPLISTENER_H 40 | 41 | -------------------------------------------------------------------------------- /TCP/Server/source.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "TCPListener.h" 3 | #include "Serialize.h" 4 | void Accept(int socketid) 5 | { 6 | char Host[NI_MAXHOST]; 7 | char Service[NI_MAXSERV]; 8 | //std::cout << "Accept" << std::endl; 9 | } 10 | void Recieve(int socketid, const char* const buffer, const int& datalength) 11 | { 12 | 13 | string Message = string(buffer, datalength); 14 | //std::cout << "Recieve : " << Message << std::endl; 15 | TCPListener::Send(socketid,Message.c_str(),Message.size()+1); 16 | } 17 | int main() 18 | { 19 | TCPListener listner = TCPListener("127.0.0.1",7071,Recieve,Accept) ; 20 | if (listner.Init()) 21 | { 22 | int a; 23 | thread th([&](){listner.Start();}); 24 | th.join(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /TCP/StepByStep/E01/Client/ClientConnection.cpp: -------------------------------------------------------------------------------- 1 | #include "ClientConnection.h" 2 | 3 | ClientConnection::ClientConnection() 4 | { 5 | 6 | } 7 | ClientConnection::ClientConnection(string ip, int port, Connection_Handler clientHandler, Recive_Handler reciveHandler) 8 | : Serverip(ip), Serverport(port), connectionHandler(clientHandler), reciveHandler(reciveHandler) 9 | { 10 | 11 | } 12 | bool ClientConnection::Init() 13 | { 14 | WSADATA WindowsSocketInof; 15 | WORD Version = MAKEWORD(2, 2); 16 | int res = WSAStartup(Version, &WindowsSocketInof); 17 | return res == 0; 18 | } 19 | void ClientConnection::Start() 20 | { 21 | MySocket = CreateSocket(); 22 | if (MySocket != INVALID_SOCKET) 23 | { 24 | IsRunning = true; 25 | connectionHandler(true); 26 | while (true) 27 | Run(); 28 | } 29 | else 30 | { 31 | throw exception("Start Function : Server Connection Failed!"); 32 | } 33 | } 34 | void ClientConnection::CleanUp() 35 | { 36 | IsRunning = false; 37 | closesocket(MySocket); 38 | WSACleanup(); 39 | } 40 | ClientConnection::~ClientConnection() 41 | { 42 | CleanUp(); 43 | } 44 | void ClientConnection::Run() 45 | { 46 | char BUFFER[SIZE_Buffer]; 47 | memset(BUFFER, 0, SIZE_Buffer); 48 | int ByteRecv = recv(MySocket, BUFFER, SIZE_Buffer, 0); 49 | if (ByteRecv <= 0) 50 | { 51 | connectionHandler( false); 52 | } 53 | else 54 | { 55 | if (ByteRecv >= 1) 56 | reciveHandler(BUFFER, ByteRecv); 57 | } 58 | } 59 | SOCKET ClientConnection::CreateSocket() 60 | { 61 | SOCKET MySocket = socket(AF_INET, SOCK_STREAM, 0); 62 | if (MySocket != INVALID_SOCKET) 63 | { 64 | sockaddr_in ServerAddress; 65 | ServerAddress.sin_family = AF_INET; // IP v4 66 | ServerAddress.sin_port = htons(Serverport); 67 | ServerAddress.sin_addr.S_un.S_addr = INADDR_ANY; 68 | int res = inet_pton(AF_INET, Serverip.c_str(), &ServerAddress.sin_addr); 69 | if (res <= 0) 70 | { 71 | CleanUp(); 72 | } 73 | else 74 | { 75 | res = connect(MySocket, (sockaddr*)&ServerAddress, sizeof(ServerAddress)); 76 | if (res != SOCKET_ERROR) 77 | { 78 | return MySocket; 79 | } 80 | else 81 | { 82 | closesocket(MySocket); 83 | CleanUp(); 84 | return -1; 85 | } 86 | } 87 | } 88 | else 89 | { 90 | closesocket(MySocket); 91 | CleanUp(); 92 | return -1; 93 | } 94 | } -------------------------------------------------------------------------------- /TCP/StepByStep/E01/Client/ClientConnection.h: -------------------------------------------------------------------------------- 1 | #ifndef CLIENTCONNECTION_H 2 | #define CLIENTCONNECTION_H 3 | #include 4 | #include 5 | #include "Packets.h" 6 | #pragma comment (lib , "Ws2_32.lib") 7 | using namespace std; 8 | typedef void (*Connection_Handler)(bool flag); 9 | typedef void (*Recive_Handler)(char* Buffer, int DataLegth); 10 | 11 | class ClientConnection 12 | { 13 | public: 14 | bool IsRunning; 15 | ClientConnection(); 16 | ClientConnection(string ip, int port, Connection_Handler, Recive_Handler); 17 | bool Init(); 18 | void Start(); 19 | void CleanUp(); 20 | ~ClientConnection(); 21 | private: 22 | 23 | Connection_Handler connectionHandler; 24 | Recive_Handler reciveHandler; 25 | string Serverip; 26 | SOCKET MySocket; 27 | int Serverport; 28 | void Run(); 29 | SOCKET CreateSocket(); 30 | 31 | }; 32 | 33 | 34 | #endif // !CLINETCONNECTION_H 35 | 36 | 37 | -------------------------------------------------------------------------------- /TCP/StepByStep/E01/Client/Packets.h: -------------------------------------------------------------------------------- 1 | #ifndef PACKET_H 2 | #define PACKET_H 3 | #define SIZE_Buffer 20 * 1024 4 | class Packets 5 | { 6 | }; 7 | #endif // !PACKET_H 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /TCP/StepByStep/E01/Client/Source.cpp: -------------------------------------------------------------------------------- 1 | #include "ClientConnection.h" 2 | #include 3 | ClientConnection tcpConnection; 4 | void Client(bool flag) 5 | { 6 | 7 | } 8 | 9 | void Reciev(char* buffer, int size) 10 | { 11 | 12 | } 13 | 14 | int main() 15 | { 16 | tcpConnection = ClientConnection("127.0.0.1", 7071, Client, Reciev); 17 | if (tcpConnection.Init()) 18 | { 19 | thread ConnectionThread = thread([&]() {tcpConnection.Start(); }); 20 | ConnectionThread.join(); 21 | } 22 | else 23 | { 24 | return 0; 25 | } 26 | } -------------------------------------------------------------------------------- /TCP/StepByStep/E01/ReadMe.md: -------------------------------------------------------------------------------- 1 | # Download Video 2 | -------------------------------------------------------------------------------- /TCP/StepByStep/E01/Server/Packets.h: -------------------------------------------------------------------------------- 1 | #ifndef PACKET_H 2 | #define PACKET_H 3 | #define SIZE_Buffer 20 * 1024 4 | class Packets 5 | { 6 | }; 7 | #endif // !PACKET_H 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /TCP/StepByStep/E01/Server/Source.cpp: -------------------------------------------------------------------------------- 1 | #include "TCPListener.h" 2 | #include 3 | #include 4 | TCPListener tcpServer; 5 | void Client(int Socketid , bool flag) 6 | { 7 | std::clog << "Connect"; 8 | } 9 | 10 | void Reciev(int socketid , char* buffer , int size) 11 | { 12 | 13 | } 14 | 15 | int main() 16 | { 17 | tcpServer = TCPListener("127.0.0.1", 7071, Client, Reciev); 18 | if (tcpServer.Init()) 19 | { 20 | thread ConnectionThread = thread([&]() {tcpServer.Start();}); 21 | ConnectionThread.join(); 22 | } 23 | else 24 | { 25 | return 0; 26 | } 27 | } -------------------------------------------------------------------------------- /TCP/StepByStep/E01/Server/TCPListener.cpp: -------------------------------------------------------------------------------- 1 | #include "TCPListener.h" 2 | TCPListener::TCPListener() 3 | { 4 | 5 | } 6 | TCPListener::TCPListener(string ip, int port, Client_Handler clientHandler, Recive_Handler reciveHandler) 7 | : ip(ip) , port(port) , clientHandler(clientHandler) , reciveHandler(reciveHandler) 8 | { 9 | 10 | } 11 | bool TCPListener::Init() 12 | { 13 | WSADATA WindowsSocketInof; 14 | WORD Version = MAKEWORD(2, 2); 15 | int res = WSAStartup(Version , &WindowsSocketInof); 16 | return res == 0; 17 | } 18 | void TCPListener::Start() 19 | { 20 | Server = CreateSocket(); 21 | if (Server != INVALID_SOCKET) 22 | { 23 | IsRunning = true; 24 | FD_ZERO(&master); 25 | FD_ZERO(&Read); 26 | FD_SET(Server, &master); 27 | Read = master; 28 | while (true) 29 | Run(); 30 | } 31 | else 32 | { 33 | throw exception("Start Function : Server Connection Failed!"); 34 | } 35 | } 36 | void TCPListener::CleanUp() 37 | { 38 | IsRunning = false; 39 | closesocket(Server); 40 | WSACleanup(); 41 | } 42 | TCPListener::~TCPListener() 43 | { 44 | CleanUp(); 45 | } 46 | void TCPListener::Run() 47 | { 48 | Read = master; 49 | int SocketCount = select(0, &Read, nullptr, nullptr, nullptr); 50 | if (SocketCount <= 0) 51 | { 52 | CleanUp(); 53 | throw exception("Run Function : Server Connection Failed!"); 54 | } 55 | else 56 | { 57 | for (int i = 0; i < SocketCount; i++) 58 | { 59 | SOCKET SelectedSocket = Read.fd_array[i]; 60 | if (SelectedSocket == Server) 61 | { 62 | SOCKET NewClient = accept(Server, nullptr, nullptr); 63 | FD_SET(NewClient, &master); 64 | clientHandler(NewClient, true); 65 | } 66 | else 67 | { 68 | char BUFFER[SIZE_Buffer]; 69 | memset(BUFFER, 0, SIZE_Buffer); 70 | int ByteRecv = recv(SelectedSocket, BUFFER, SIZE_Buffer, 0); 71 | if (ByteRecv <= 0) 72 | { 73 | FD_CLR(SelectedSocket , &master); 74 | clientHandler(SelectedSocket, false); 75 | } 76 | else 77 | { 78 | if (ByteRecv >= 1) 79 | reciveHandler(SelectedSocket, BUFFER, ByteRecv); 80 | } 81 | } 82 | } 83 | } 84 | } 85 | SOCKET TCPListener::CreateSocket() 86 | { 87 | SOCKET Server = socket(AF_INET, SOCK_STREAM, 0); 88 | if (Server != INVALID_SOCKET) 89 | { 90 | sockaddr_in ServerAddress; 91 | ServerAddress.sin_family = AF_INET; // IP v4 92 | ServerAddress.sin_port = htons(port); 93 | ServerAddress.sin_addr.S_un.S_addr = INADDR_ANY; 94 | int res = ::bind(Server , (sockaddr*)&ServerAddress , sizeof(ServerAddress)); 95 | if (res != SOCKET_ERROR) 96 | { 97 | res = listen(Server, SOMAXCONN); 98 | if (res != SOCKET_ERROR) 99 | { 100 | return Server; 101 | } 102 | else 103 | { 104 | closesocket(Server); 105 | CleanUp(); 106 | return -1; 107 | } 108 | } 109 | else 110 | { 111 | closesocket(Server); 112 | CleanUp(); 113 | return -1; 114 | } 115 | } 116 | else 117 | { 118 | closesocket(Server); 119 | CleanUp(); 120 | return -1; 121 | } 122 | } -------------------------------------------------------------------------------- /TCP/StepByStep/E01/Server/TCPListener.h: -------------------------------------------------------------------------------- 1 | #ifndef TCPListener_H 2 | #define TCPListener_H 3 | #include 4 | #include 5 | #include "Packets.h" 6 | #pragma comment (lib , "Ws2_32.lib") 7 | using namespace std; 8 | typedef void (*Client_Handler)(int SocketID, bool flag); 9 | typedef void (*Recive_Handler)(int SockerID, char* Buffer, int DataLegth); 10 | 11 | class TCPListener 12 | { 13 | public: 14 | bool IsRunning; 15 | TCPListener(); 16 | TCPListener(string ip, int port, Client_Handler , Recive_Handler); 17 | bool Init(); 18 | void Start(); 19 | void CleanUp(); 20 | ~TCPListener(); 21 | private: 22 | fd_set master; 23 | fd_set Read; 24 | Client_Handler clientHandler; 25 | Recive_Handler reciveHandler; 26 | string ip; 27 | SOCKET Server; 28 | int port; 29 | void Run(); 30 | SOCKET CreateSocket(); 31 | }; 32 | #endif // !TCPListener_H 33 | -------------------------------------------------------------------------------- /TCP/StepByStep/E02/Client/Packets.h: -------------------------------------------------------------------------------- 1 | #ifndef PACKET_H 2 | #define PACKET_H 3 | #define SIZE_Buffer (20*1024) 4 | #define SIZE_FileBuffer (SIZE_Buffer-12)-1 5 | #define SIZE_Message 1024 6 | #define SIZE_MessageBuffer SIZE_Message-8-1 7 | 8 | enum Header : char 9 | { 10 | queue, 11 | start, 12 | chunck, 13 | message 14 | }; 15 | struct Packet 16 | { 17 | Header header; 18 | }; 19 | struct StartPacket : public Packet 20 | { 21 | int QueueID; 22 | }; 23 | struct QueuePacket : public Packet 24 | { 25 | char FileName[165]; 26 | char FileExtention[205]; 27 | long Size; 28 | int QueueID; 29 | QueuePacket() 30 | { 31 | memset(FileName, 0, 165); 32 | memset(FileExtention, 0, 205); 33 | } 34 | }; 35 | struct FilePacket : public Packet 36 | { 37 | int QueueId; 38 | int Read; 39 | char Buffer[SIZE_FileBuffer]; 40 | FilePacket() 41 | { 42 | memset(Buffer, 0, SIZE_FileBuffer); 43 | } 44 | 45 | }; 46 | struct MessagePacket : public Packet 47 | { 48 | int size; 49 | char Buffer[SIZE_MessageBuffer]; 50 | MessagePacket() 51 | { 52 | memset(Buffer, 0, SIZE_MessageBuffer); 53 | } 54 | }; 55 | #endif // !PACKET_H 56 | -------------------------------------------------------------------------------- /TCP/StepByStep/E02/Client/Serialize.h: -------------------------------------------------------------------------------- 1 | #ifndef SERIALIZE_H 2 | #define SERIALIZE_H 3 | #include 4 | template 5 | class Serialize 6 | { 7 | public: 8 | static size_t size(const Type input) 9 | { 10 | return sizeof(input); 11 | } 12 | static size_t serialize(char* const Buffer , Type input) 13 | { 14 | memcpy(Buffer, &input, sizeof(input)); 15 | return sizeof(input); 16 | } 17 | static size_t deserialize(char* Buffer, Type& output) 18 | { 19 | memcpy(&output, Buffer, sizeof(output)); 20 | return sizeof(output); 21 | } 22 | }; 23 | #endif // !SERIALIZE_H 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /TCP/StepByStep/E02/Client/Source.cpp: -------------------------------------------------------------------------------- 1 | #include "TCPListener.h" 2 | #include "Serialize.h" 3 | #include 4 | #include 5 | #include 6 | map ClientList; 7 | static int ClientNum = 0; 8 | TCPListener tcpServer; 9 | std::mutex ClientLiatDoor; 10 | void Client(int Socketid , bool flag) 11 | { 12 | std::lock_guardDoor(ClientLiatDoor); 13 | std::clog << "\nNew Connect\n"; 14 | if (flag) 15 | { 16 | ClientList.insert(pair("Amirreza" + to_string(ClientNum++), Socketid)); 17 | } 18 | else 19 | { 20 | string username; 21 | for (auto target : ClientList) 22 | { 23 | if (target.second == Socketid) 24 | { 25 | username = target.first; 26 | break; 27 | } 28 | } 29 | ClientList.erase(username); 30 | } 31 | } 32 | 33 | void Reciev(int socketid , char* buffer , int size) 34 | { 35 | Packet pk; 36 | Serialize::deserialize(buffer, pk); 37 | switch (pk.header) 38 | { 39 | case Header::message: 40 | { 41 | MessagePacket msp; 42 | Serialize::deserialize(buffer, msp); 43 | string username; 44 | for (auto target : ClientList) 45 | { 46 | if (target.second == socketid) 47 | { 48 | username = target.first; 49 | break; 50 | } 51 | } 52 | cout << username << string(msp.Buffer, msp.size) << endl; 53 | } 54 | default: 55 | break; 56 | } 57 | } 58 | void sendmessage() 59 | { 60 | while (!tcpServer.IsRunning); 61 | 62 | cout << "\nEnter your Message : "; 63 | string message; 64 | getline(cin, message); 65 | 66 | // Packting 67 | MessagePacket msp; 68 | msp.header = Header::message; 69 | msp.size = message.length(); 70 | memcpy(msp.Buffer, message.c_str(), msp.size); 71 | 72 | string username; 73 | ClientLiatDoor.lock(); 74 | do 75 | { 76 | cout << "Enter UserName : "; 77 | getline(cin, username); 78 | } while (ClientList.find(username) == ClientList.end()); 79 | int ClinetID = ClientList.find(username)->second; 80 | ClientLiatDoor.unlock(); 81 | 82 | char BUFFER[SIZE_Message]; 83 | memset(BUFFER, 0, SIZE_Message); 84 | Serialize::serialize(BUFFER, msp); 85 | 86 | send(ClinetID, BUFFER, SIZE_Message, 0); 87 | } 88 | int main() 89 | { 90 | tcpServer = TCPListener("127.0.0.1", 7071, Client, Reciev); 91 | if (tcpServer.Init()) 92 | { 93 | thread ConnectionThread = thread([&]() {tcpServer.Start();}); 94 | thread SendThread = thread([&]() { 95 | while(true) 96 | sendmessage(); 97 | }); 98 | ConnectionThread.join(); 99 | SendThread.join(); 100 | } 101 | else 102 | { 103 | return 0; 104 | } 105 | } -------------------------------------------------------------------------------- /TCP/StepByStep/E02/Client/TCPListener.cpp: -------------------------------------------------------------------------------- 1 | #include "TCPListener.h" 2 | TCPListener::TCPListener() 3 | { 4 | 5 | } 6 | TCPListener::TCPListener(string ip, int port, Client_Handler clientHandler, Recive_Handler reciveHandler) 7 | : ip(ip) , port(port) , clientHandler(clientHandler) , reciveHandler(reciveHandler) 8 | { 9 | 10 | } 11 | bool TCPListener::Init() 12 | { 13 | WSADATA WindowsSocketInof; 14 | WORD Version = MAKEWORD(2, 2); 15 | int res = WSAStartup(Version , &WindowsSocketInof); 16 | return res == 0; 17 | } 18 | void TCPListener::Start() 19 | { 20 | Server = CreateSocket(); 21 | if (Server != INVALID_SOCKET) 22 | { 23 | IsRunning = true; 24 | FD_ZERO(&master); 25 | FD_ZERO(&Read); 26 | FD_SET(Server, &master); 27 | Read = master; 28 | while (true) 29 | Run(); 30 | } 31 | else 32 | { 33 | throw exception("Start Function : Server Connection Failed!"); 34 | } 35 | } 36 | void TCPListener::CleanUp() 37 | { 38 | IsRunning = false; 39 | closesocket(Server); 40 | WSACleanup(); 41 | } 42 | TCPListener::~TCPListener() 43 | { 44 | CleanUp(); 45 | } 46 | void TCPListener::Run() 47 | { 48 | Read = master; 49 | int SocketCount = select(0, &Read, nullptr, nullptr, nullptr); 50 | if (SocketCount <= 0) 51 | { 52 | CleanUp(); 53 | throw exception("Run Function : Server Connection Failed!"); 54 | } 55 | else 56 | { 57 | for (int i = 0; i < SocketCount; i++) 58 | { 59 | SOCKET SelectedSocket = Read.fd_array[i]; 60 | if (SelectedSocket == Server) 61 | { 62 | SOCKET NewClient = accept(Server, nullptr, nullptr); 63 | FD_SET(NewClient, &master); 64 | clientHandler(NewClient, true); 65 | } 66 | else 67 | { 68 | char BUFFER[SIZE_Buffer]; 69 | memset(BUFFER, 0, SIZE_Buffer); 70 | int ByteRecv = recv(SelectedSocket, BUFFER, SIZE_Buffer, 0); 71 | if (ByteRecv <= 0) 72 | { 73 | FD_CLR(SelectedSocket , &master); 74 | clientHandler(SelectedSocket, false); 75 | } 76 | else 77 | { 78 | if (ByteRecv >= 1) 79 | reciveHandler(SelectedSocket, BUFFER, ByteRecv); 80 | } 81 | } 82 | } 83 | } 84 | } 85 | SOCKET TCPListener::CreateSocket() 86 | { 87 | SOCKET Server = socket(AF_INET, SOCK_STREAM, 0); 88 | if (Server != INVALID_SOCKET) 89 | { 90 | sockaddr_in ServerAddress; 91 | ServerAddress.sin_family = AF_INET; // IP v4 92 | ServerAddress.sin_port = htons(port); 93 | ServerAddress.sin_addr.S_un.S_addr = INADDR_ANY; 94 | int res = ::bind(Server , (sockaddr*)&ServerAddress , sizeof(ServerAddress)); 95 | if (res != SOCKET_ERROR) 96 | { 97 | res = listen(Server, SOMAXCONN); 98 | if (res != SOCKET_ERROR) 99 | { 100 | return Server; 101 | } 102 | else 103 | { 104 | closesocket(Server); 105 | CleanUp(); 106 | return -1; 107 | } 108 | } 109 | else 110 | { 111 | closesocket(Server); 112 | CleanUp(); 113 | return -1; 114 | } 115 | } 116 | else 117 | { 118 | closesocket(Server); 119 | CleanUp(); 120 | return -1; 121 | } 122 | } -------------------------------------------------------------------------------- /TCP/StepByStep/E02/Client/TCPListener.h: -------------------------------------------------------------------------------- 1 | #ifndef TCPListener_H 2 | #define TCPListener_H 3 | #include 4 | #include 5 | #include "Packets.h" 6 | #include 7 | 8 | #pragma comment (lib , "Ws2_32.lib") 9 | using namespace std; 10 | typedef void (*Client_Handler)(int SocketID, bool flag); 11 | typedef void (*Recive_Handler)(int SockerID, char* Buffer, int DataLegth); 12 | 13 | class TCPListener 14 | { 15 | public: 16 | bool IsRunning; 17 | TCPListener(); 18 | TCPListener(string ip, int port, Client_Handler , Recive_Handler); 19 | bool Init(); 20 | void Start(); 21 | void CleanUp(); 22 | ~TCPListener(); 23 | private: 24 | fd_set master; 25 | fd_set Read; 26 | Client_Handler clientHandler; 27 | Recive_Handler reciveHandler; 28 | string ip; 29 | SOCKET Server; 30 | int port; 31 | void Run(); 32 | SOCKET CreateSocket(); 33 | }; 34 | #endif // !TCPListener_H 35 | -------------------------------------------------------------------------------- /TCP/StepByStep/E02/ReadMe.md: -------------------------------------------------------------------------------- 1 | # Download Video 2 | -------------------------------------------------------------------------------- /TCP/StepByStep/E02/Server/Packets.h: -------------------------------------------------------------------------------- 1 | #ifndef PACKET_H 2 | #define PACKET_H 3 | #define SIZE_Buffer (20*1024) 4 | #define SIZE_FileBuffer (SIZE_Buffer-12)-1 5 | #define SIZE_Message 1024 6 | #define SIZE_MessageBuffer SIZE_Message-8-1 7 | 8 | enum Header : char 9 | { 10 | queue, 11 | start, 12 | chunck, 13 | message 14 | }; 15 | struct Packet 16 | { 17 | Header header; 18 | }; 19 | struct StartPacket : public Packet 20 | { 21 | int QueueID; 22 | }; 23 | struct QueuePacket : public Packet 24 | { 25 | char FileName[165]; 26 | char FileExtention[205]; 27 | long Size; 28 | int QueueID; 29 | QueuePacket() 30 | { 31 | memset(FileName, 0, 165); 32 | memset(FileExtention, 0, 205); 33 | } 34 | }; 35 | struct FilePacket : public Packet 36 | { 37 | int QueueId; 38 | int Read; 39 | char Buffer[SIZE_FileBuffer]; 40 | FilePacket() 41 | { 42 | memset(Buffer, 0, SIZE_FileBuffer); 43 | } 44 | 45 | }; 46 | struct MessagePacket : public Packet 47 | { 48 | int size; 49 | char Buffer[SIZE_MessageBuffer]; 50 | MessagePacket() 51 | { 52 | memset(Buffer, 0, SIZE_MessageBuffer); 53 | } 54 | }; 55 | #endif // !PACKET_H 56 | -------------------------------------------------------------------------------- /TCP/StepByStep/E02/Server/Serialize.h: -------------------------------------------------------------------------------- 1 | #ifndef SERIALIZE_H 2 | #define SERIALIZE_H 3 | #include 4 | template 5 | class Serialize 6 | { 7 | public: 8 | static size_t size(const Type input) 9 | { 10 | return sizeof(input); 11 | } 12 | static size_t serialize(char* const Buffer , Type input) 13 | { 14 | memcpy(Buffer, &input, sizeof(input)); 15 | return sizeof(input); 16 | } 17 | static size_t deserialize(char* Buffer, Type& output) 18 | { 19 | memcpy(&output, Buffer, sizeof(output)); 20 | return sizeof(output); 21 | } 22 | }; 23 | #endif // !SERIALIZE_H 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /TCP/StepByStep/E02/Server/Source.cpp: -------------------------------------------------------------------------------- 1 | #include "TCPListener.h" 2 | #include "Serialize.h" 3 | #include 4 | #include 5 | #include 6 | map ClientList; 7 | static int ClientNum = 0; 8 | TCPListener tcpServer; 9 | std::mutex ClientLiatDoor; 10 | void Client(int Socketid , bool flag) 11 | { 12 | std::lock_guardDoor(ClientLiatDoor); 13 | std::clog << "\nNew Connect\n"; 14 | if (flag) 15 | { 16 | ClientList.insert(pair("Amirreza" + to_string(ClientNum++), Socketid)); 17 | } 18 | else 19 | { 20 | string username; 21 | for (auto target : ClientList) 22 | { 23 | if (target.second == Socketid) 24 | { 25 | username = target.first; 26 | break; 27 | } 28 | } 29 | ClientList.erase(username); 30 | } 31 | } 32 | 33 | void Reciev(int socketid , char* buffer , int size) 34 | { 35 | Packet pk; 36 | Serialize::deserialize(buffer, pk); 37 | switch (pk.header) 38 | { 39 | case Header::message: 40 | { 41 | MessagePacket msp; 42 | Serialize::deserialize(buffer, msp); 43 | string username; 44 | for (auto target : ClientList) 45 | { 46 | if (target.second == socketid) 47 | { 48 | username = target.first; 49 | break; 50 | } 51 | } 52 | cout << username << string(msp.Buffer, msp.size) << endl; 53 | } 54 | default: 55 | break; 56 | } 57 | } 58 | void sendmessage() 59 | { 60 | while (!tcpServer.IsRunning); 61 | 62 | cout << "\nEnter your Message : "; 63 | string message; 64 | getline(cin, message); 65 | 66 | // Packting 67 | MessagePacket msp; 68 | msp.header = Header::message; 69 | msp.size = message.length(); 70 | memcpy(msp.Buffer, message.c_str(), msp.size); 71 | 72 | string username; 73 | ClientLiatDoor.lock(); 74 | do 75 | { 76 | cout << "Enter UserName : "; 77 | getline(cin, username); 78 | } while (ClientList.find(username) == ClientList.end()); 79 | int ClinetID = ClientList.find(username)->second; 80 | ClientLiatDoor.unlock(); 81 | 82 | char BUFFER[SIZE_Message]; 83 | memset(BUFFER, 0, SIZE_Message); 84 | Serialize::serialize(BUFFER, msp); 85 | 86 | send(ClinetID, BUFFER, SIZE_Message, 0); 87 | } 88 | int main() 89 | { 90 | tcpServer = TCPListener("127.0.0.1", 7071, Client, Reciev); 91 | if (tcpServer.Init()) 92 | { 93 | thread ConnectionThread = thread([&]() {tcpServer.Start();}); 94 | thread SendThread = thread([&]() { 95 | while(true) 96 | sendmessage(); 97 | }); 98 | ConnectionThread.join(); 99 | SendThread.join(); 100 | } 101 | else 102 | { 103 | return 0; 104 | } 105 | } -------------------------------------------------------------------------------- /TCP/StepByStep/E02/Server/TCPListener.cpp: -------------------------------------------------------------------------------- 1 | #include "TCPListener.h" 2 | TCPListener::TCPListener() 3 | { 4 | 5 | } 6 | TCPListener::TCPListener(string ip, int port, Client_Handler clientHandler, Recive_Handler reciveHandler) 7 | : ip(ip) , port(port) , clientHandler(clientHandler) , reciveHandler(reciveHandler) 8 | { 9 | 10 | } 11 | bool TCPListener::Init() 12 | { 13 | WSADATA WindowsSocketInof; 14 | WORD Version = MAKEWORD(2, 2); 15 | int res = WSAStartup(Version , &WindowsSocketInof); 16 | return res == 0; 17 | } 18 | void TCPListener::Start() 19 | { 20 | Server = CreateSocket(); 21 | if (Server != INVALID_SOCKET) 22 | { 23 | IsRunning = true; 24 | FD_ZERO(&master); 25 | FD_ZERO(&Read); 26 | FD_SET(Server, &master); 27 | Read = master; 28 | while (true) 29 | Run(); 30 | } 31 | else 32 | { 33 | throw exception("Start Function : Server Connection Failed!"); 34 | } 35 | } 36 | void TCPListener::CleanUp() 37 | { 38 | IsRunning = false; 39 | closesocket(Server); 40 | WSACleanup(); 41 | } 42 | TCPListener::~TCPListener() 43 | { 44 | CleanUp(); 45 | } 46 | void TCPListener::Run() 47 | { 48 | Read = master; 49 | int SocketCount = select(0, &Read, nullptr, nullptr, nullptr); 50 | if (SocketCount <= 0) 51 | { 52 | CleanUp(); 53 | throw exception("Run Function : Server Connection Failed!"); 54 | } 55 | else 56 | { 57 | for (int i = 0; i < SocketCount; i++) 58 | { 59 | SOCKET SelectedSocket = Read.fd_array[i]; 60 | if (SelectedSocket == Server) 61 | { 62 | SOCKET NewClient = accept(Server, nullptr, nullptr); 63 | FD_SET(NewClient, &master); 64 | clientHandler(NewClient, true); 65 | } 66 | else 67 | { 68 | char BUFFER[SIZE_Buffer]; 69 | memset(BUFFER, 0, SIZE_Buffer); 70 | int ByteRecv = recv(SelectedSocket, BUFFER, SIZE_Buffer, 0); 71 | if (ByteRecv <= 0) 72 | { 73 | FD_CLR(SelectedSocket , &master); 74 | clientHandler(SelectedSocket, false); 75 | } 76 | else 77 | { 78 | if (ByteRecv >= 1) 79 | reciveHandler(SelectedSocket, BUFFER, ByteRecv); 80 | } 81 | } 82 | } 83 | } 84 | } 85 | SOCKET TCPListener::CreateSocket() 86 | { 87 | SOCKET Server = socket(AF_INET, SOCK_STREAM, 0); 88 | if (Server != INVALID_SOCKET) 89 | { 90 | sockaddr_in ServerAddress; 91 | ServerAddress.sin_family = AF_INET; // IP v4 92 | ServerAddress.sin_port = htons(port); 93 | ServerAddress.sin_addr.S_un.S_addr = INADDR_ANY; 94 | int res = ::bind(Server , (sockaddr*)&ServerAddress , sizeof(ServerAddress)); 95 | if (res != SOCKET_ERROR) 96 | { 97 | res = listen(Server, SOMAXCONN); 98 | if (res != SOCKET_ERROR) 99 | { 100 | return Server; 101 | } 102 | else 103 | { 104 | closesocket(Server); 105 | CleanUp(); 106 | return -1; 107 | } 108 | } 109 | else 110 | { 111 | closesocket(Server); 112 | CleanUp(); 113 | return -1; 114 | } 115 | } 116 | else 117 | { 118 | closesocket(Server); 119 | CleanUp(); 120 | return -1; 121 | } 122 | } -------------------------------------------------------------------------------- /TCP/StepByStep/E02/Server/TCPListener.h: -------------------------------------------------------------------------------- 1 | #ifndef TCPListener_H 2 | #define TCPListener_H 3 | #include 4 | #include 5 | #include "Packets.h" 6 | #include 7 | 8 | #pragma comment (lib , "Ws2_32.lib") 9 | using namespace std; 10 | typedef void (*Client_Handler)(int SocketID, bool flag); 11 | typedef void (*Recive_Handler)(int SockerID, char* Buffer, int DataLegth); 12 | 13 | class TCPListener 14 | { 15 | public: 16 | bool IsRunning; 17 | TCPListener(); 18 | TCPListener(string ip, int port, Client_Handler , Recive_Handler); 19 | bool Init(); 20 | void Start(); 21 | void CleanUp(); 22 | ~TCPListener(); 23 | private: 24 | fd_set master; 25 | fd_set Read; 26 | Client_Handler clientHandler; 27 | Recive_Handler reciveHandler; 28 | string ip; 29 | SOCKET Server; 30 | int port; 31 | void Run(); 32 | SOCKET CreateSocket(); 33 | }; 34 | #endif // !TCPListener_H 35 | -------------------------------------------------------------------------------- /TCP/StepByStep/E03/Client/ClientConnection.cpp: -------------------------------------------------------------------------------- 1 | #include "ClientConnection.h" 2 | 3 | ClientConnection::ClientConnection() 4 | { 5 | 6 | } 7 | ClientConnection::ClientConnection(string ip, int port, Connection_Handler clientHandler, Recive_Handler reciveHandler) 8 | : Serverip(ip), Serverport(port), connectionHandler(clientHandler), reciveHandler(reciveHandler) 9 | { 10 | 11 | } 12 | bool ClientConnection::Init() 13 | { 14 | WSADATA WindowsSocketInof; 15 | WORD Version = MAKEWORD(2, 2); 16 | int res = WSAStartup(Version, &WindowsSocketInof); 17 | return res == 0; 18 | } 19 | void ClientConnection::Start() 20 | { 21 | MySocket = CreateSocket(); 22 | if (MySocket != INVALID_SOCKET) 23 | { 24 | IsRunning = true; 25 | connectionHandler(true); 26 | while (true) 27 | Run(); 28 | } 29 | else 30 | { 31 | throw exception("Start Function : Server Connection Failed!"); 32 | } 33 | } 34 | void ClientConnection::CleanUp() 35 | { 36 | IsRunning = false; 37 | closesocket(MySocket); 38 | WSACleanup(); 39 | } 40 | ClientConnection::~ClientConnection() 41 | { 42 | CleanUp(); 43 | } 44 | void ClientConnection::Run() 45 | { 46 | char BUFFER[SIZE_Buffer]; 47 | memset(BUFFER, 0, SIZE_Buffer); 48 | int ByteRecv = recv(MySocket, BUFFER, SIZE_Buffer, 0); 49 | if (ByteRecv <= 0) 50 | { 51 | connectionHandler( false); 52 | } 53 | else 54 | { 55 | if (ByteRecv >= 1) 56 | reciveHandler(BUFFER, ByteRecv); 57 | } 58 | } 59 | SOCKET ClientConnection::CreateSocket() 60 | { 61 | SOCKET MySocket = socket(AF_INET, SOCK_STREAM, 0); 62 | if (MySocket != INVALID_SOCKET) 63 | { 64 | sockaddr_in ServerAddress; 65 | ServerAddress.sin_family = AF_INET; // IP v4 66 | ServerAddress.sin_port = htons(Serverport); 67 | ServerAddress.sin_addr.S_un.S_addr = INADDR_ANY; 68 | int res = inet_pton(AF_INET, Serverip.c_str(), &ServerAddress.sin_addr); 69 | if (res <= 0) 70 | { 71 | CleanUp(); 72 | } 73 | else 74 | { 75 | res = connect(MySocket, (sockaddr*)&ServerAddress, sizeof(ServerAddress)); 76 | if (res != SOCKET_ERROR) 77 | { 78 | return MySocket; 79 | } 80 | else 81 | { 82 | closesocket(MySocket); 83 | CleanUp(); 84 | return -1; 85 | } 86 | } 87 | } 88 | else 89 | { 90 | closesocket(MySocket); 91 | CleanUp(); 92 | return -1; 93 | } 94 | } -------------------------------------------------------------------------------- /TCP/StepByStep/E03/Client/ClientConnection.h: -------------------------------------------------------------------------------- 1 | #ifndef CLINETCONNECTION_H 2 | #define CLINETCONNECTION_H 3 | #include 4 | #include 5 | #include "Packets.h" 6 | #pragma comment (lib , "Ws2_32.lib") 7 | using namespace std; 8 | typedef void (*Connection_Handler)(bool flag); 9 | typedef void (*Recive_Handler)(char* Buffer, int DataLegth); 10 | 11 | class ClientConnection 12 | { 13 | public: 14 | bool IsRunning; 15 | SOCKET MySocket; 16 | ClientConnection(); 17 | ClientConnection(string ip, int port, Connection_Handler, Recive_Handler); 18 | bool Init(); 19 | void Start(); 20 | void CleanUp(); 21 | ~ClientConnection(); 22 | private: 23 | 24 | Connection_Handler connectionHandler; 25 | Recive_Handler reciveHandler; 26 | string Serverip; 27 | int Serverport; 28 | void Run(); 29 | SOCKET CreateSocket(); 30 | 31 | }; 32 | 33 | 34 | #endif // !CLINETCONNECTION_H 35 | 36 | 37 | -------------------------------------------------------------------------------- /TCP/StepByStep/E03/Client/FileHandler.h: -------------------------------------------------------------------------------- 1 | #ifndef FILEHANDLER_H 2 | #define FILEHANDLER_H 3 | #include 4 | #include 5 | using std::string; 6 | using std::ifstream; 7 | class FileHandler 8 | { 9 | public: 10 | static string GetFileName(string path) 11 | { 12 | for (int i = path.length(); i >= 0; i--) 13 | if (path[i] == '\\') 14 | return path.substr(i + 1); 15 | return path; 16 | } 17 | static string GetFileExtention(string path) 18 | { 19 | string filename = GetFileName(path); 20 | size_t i = filename.rfind('.', filename.length()); 21 | if (i != string::npos) { 22 | return(filename.substr(i, filename.length() - i)); 23 | } 24 | } 25 | static string GetFileNameWhitOutExtention(string path) 26 | { 27 | string filename = GetFileName(path); 28 | size_t i = filename.rfind('.', filename.length()); 29 | if (i != string::npos) { 30 | return(filename.substr(0, i)); 31 | } 32 | } 33 | static inline string Combine(string str1, string str2) 34 | { 35 | return str1 + "\\" + str2; 36 | } 37 | static inline string TempPath(string Filename, string Extention = ".tmp") 38 | { 39 | while (IsFileExist(Filename + Extention)) 40 | Filename += "_copy"; 41 | return Filename + Extention; 42 | 43 | } 44 | static inline bool IsFileExist(const string& name) { 45 | ifstream f(name.c_str()); 46 | return f.good(); 47 | } 48 | static bool ConvertTmpToStableFile(const string& tmppath, const string& destinationpath) 49 | { 50 | string fname; 51 | if (GetFileNameWhitOutExtention(destinationpath) != "") 52 | fname = GetFileNameWhitOutExtention(destinationpath) + GetFileExtention(destinationpath); 53 | else 54 | fname = GetFileNameWhitOutExtention(tmppath) + GetFileExtention(destinationpath); 55 | 56 | if (!IsFileExist(tmppath)) 57 | return 0; 58 | 59 | if (rename(tmppath.c_str(), fname.c_str()) != 0) 60 | ConvertTmpToStableFile(tmppath, GetFileNameWhitOutExtention(fname) + "_Copy" + GetFileExtention(destinationpath)); 61 | else 62 | return 1; 63 | } 64 | }; 65 | #endif -------------------------------------------------------------------------------- /TCP/StepByStep/E03/Client/Packets.h: -------------------------------------------------------------------------------- 1 | #ifndef PACKET_H 2 | #define PACKET_H 3 | #define SIZE_Buffer (20*1024) 4 | #define SIZE_FileBuffer (SIZE_Buffer-12)-1 5 | #define SIZE_Message 1024 6 | #define SIZE_MessageBuffer SIZE_Message-8-1 7 | 8 | enum Header : char 9 | { 10 | queue, 11 | start, 12 | chunck, 13 | message 14 | }; 15 | struct Packet 16 | { 17 | Header header; 18 | }; 19 | struct StartPacket : public Packet 20 | { 21 | int QueueID; 22 | }; 23 | struct QueuePacket : public Packet 24 | { 25 | char FileName[165]; 26 | char FileExtention[205]; 27 | long Size; 28 | int QueueID; 29 | QueuePacket() 30 | { 31 | memset(FileName, 0, 165); 32 | memset(FileExtention, 0, 205); 33 | } 34 | }; 35 | struct FilePacket : public Packet 36 | { 37 | int QueueId; 38 | int Read; 39 | char Buffer[SIZE_FileBuffer]; 40 | FilePacket() 41 | { 42 | memset(Buffer, 0, SIZE_FileBuffer); 43 | } 44 | 45 | }; 46 | struct MessagePacket : public Packet 47 | { 48 | int size; 49 | char Buffer[SIZE_MessageBuffer]; 50 | MessagePacket() 51 | { 52 | memset(Buffer, 0, SIZE_MessageBuffer); 53 | } 54 | }; 55 | #endif // !PACKET_H 56 | -------------------------------------------------------------------------------- /TCP/StepByStep/E03/Client/Queue.cpp: -------------------------------------------------------------------------------- 1 | #include "Queue.h" 2 | 3 | Queue* Queue::Upload(int socketid, string path, int QueueID, ChanheProgress chanheprogress) 4 | { 5 | try 6 | { 7 | Queue* item = new Queue(); 8 | item->QueueID = QueueID; 9 | item->chanheprogress = chanheprogress; 10 | item->SocketID = socketid; 11 | item->FileName = FileHandler::GetFileNameWhitOutExtention(path); 12 | item->FileExtention = FileHandler::GetFileExtention(path); 13 | item->FilePath = path; 14 | item->Index = 0; 15 | item->Treansfered = 0; 16 | item->Progress = 0; 17 | item->LastProgress = 0; 18 | item->Type = QueueTYPE::upload; 19 | item->readfile = std::ifstream(path, std::ios::binary); 20 | if (!item->readfile.is_open()) 21 | return nullptr; 22 | item->Length = item->readfile.seekg(0, std::ios::end).tellg(); 23 | item->readfile.seekg(0); 24 | return item; 25 | } 26 | catch (...) 27 | { 28 | return nullptr; 29 | } 30 | } 31 | Queue* Queue::Download(int socketid, int QueueID, string FileName, string FileExtention, long size, ChanheProgress chanheprogress) 32 | { 33 | try 34 | { 35 | Queue* item = new Queue(); 36 | item->QueueID = QueueID; 37 | item->chanheprogress = chanheprogress; 38 | item->SocketID = socketid; 39 | item->FileName = FileName; 40 | item->FileExtention = FileExtention; 41 | item->FilePath = FileHandler::Combine(".", FileHandler::TempPath(FileName)); 42 | item->Index = 0; 43 | item->Treansfered = 0; 44 | item->Progress = 0; 45 | item->LastProgress = 0; 46 | item->Type = QueueTYPE::download; 47 | item->writefile = std::ofstream(item->FilePath, std::ios::binary); 48 | if (!item->writefile.is_open()) 49 | return nullptr; 50 | item->Length = size; 51 | return item; 52 | 53 | } 54 | catch (...) 55 | { 56 | return nullptr; 57 | } 58 | } 59 | void Queue::SetProgress(int read) 60 | { 61 | this->Index += read; 62 | this->Treansfered += read; 63 | this->Progress = (int)((this->Treansfered * 100) / this->Length); 64 | if (this->LastProgress < this->Progress) 65 | this->LastProgress = this->Progress; 66 | if (this->LastProgress == 100) 67 | this->Close(); 68 | if (chanheprogress != NULL) 69 | chanheprogress(this->QueueID , this->LastProgress); 70 | 71 | } 72 | void Queue::Start() 73 | { 74 | this->Running = true; 75 | this->SendThread = thread([&]() {TrenasferProc(this); }); 76 | } 77 | void Queue::Close() 78 | { 79 | if (this->Type == QueueTYPE::download) 80 | { 81 | this->writefile.close(); 82 | FileHandler::ConvertTmpToStableFile(this->FilePath, this->FileExtention); 83 | } 84 | else if (this->Type == QueueTYPE::upload) 85 | { 86 | this->readfile.close(); 87 | this->Running = false; 88 | this->SendThread.detach(); 89 | } 90 | } 91 | void Queue::Write(const char const* Buffer, int Read) 92 | { 93 | this->writefile.write(Buffer, Read); 94 | SetProgress(Read); 95 | } 96 | void Queue::TrenasferProc(Queue* item) 97 | { 98 | while (item->Running && item->Index < item->Length) 99 | { 100 | sendDoor.lock(); 101 | 102 | long read = (item->Length - item->Index < SIZE_FileBuffer) ? item->Length - item->Index : SIZE_FileBuffer; 103 | 104 | FilePacket fp; 105 | fp.header = Header::chunck; 106 | fp.QueueId = item->QueueID; 107 | fp.Read = read; 108 | item->readfile.read(fp.Buffer, read); 109 | 110 | char Buffer[SIZE_Buffer]; 111 | memset(Buffer, 0, SIZE_Buffer); 112 | int size = Serialize< FilePacket>::serialize(Buffer, fp); 113 | send(this->SocketID, Buffer, size, 0); 114 | SetProgress(read); 115 | sendDoor.unlock(); 116 | std::this_thread::sleep_for(std::chrono::microseconds(5)); 117 | } 118 | } 119 | Queue::Queue() 120 | { 121 | 122 | } -------------------------------------------------------------------------------- /TCP/StepByStep/E03/Client/Queue.h: -------------------------------------------------------------------------------- 1 | #ifndef QUEUE_H 2 | #define QUEUE_H 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "FileHandler.h" 9 | #include "Packets.h" 10 | #include "Serialize.h" 11 | #include "ClientConnection.h" 12 | using namespace std; 13 | class Queue; 14 | 15 | typedef void(__stdcall* ChanheProgress)(int Queueid, int value); 16 | enum QueueTYPE 17 | { 18 | download, 19 | upload 20 | }; 21 | class Queue 22 | { 23 | private: 24 | 25 | Queue(); 26 | void TrenasferProc(Queue*); 27 | string FilePath; 28 | thread SendThread; 29 | mutex sendDoor; 30 | ifstream readfile; 31 | ofstream writefile; 32 | long Treansfered; 33 | long Index; 34 | int Progress, LastProgress; 35 | bool Running; 36 | int SocketID; 37 | ChanheProgress chanheprogress; 38 | public: 39 | string FileName; 40 | string FileExtention; 41 | long Length; 42 | int QueueID; 43 | QueueTYPE Type; 44 | static Queue* Upload(int socketid, string path, int QueueID, ChanheProgress chanheprogress); 45 | static Queue* Download(int socketid, int QueueID, string FileName, string FileExtention, long size, ChanheProgress chanheprogress); 46 | void SetProgress(int read); 47 | void Start(); 48 | void Close(); 49 | void Write(const char const* Buffer, int Read); 50 | 51 | }; 52 | #endif // !QUEUE_H 53 | -------------------------------------------------------------------------------- /TCP/StepByStep/E03/Client/Serialize.h: -------------------------------------------------------------------------------- 1 | #ifndef SERIALIZE_H 2 | #define SERIALIZE_H 3 | #include 4 | template 5 | class Serialize 6 | { 7 | public: 8 | static size_t size(const Type input) 9 | { 10 | return sizeof(input); 11 | } 12 | static size_t serialize(char* const Buffer , Type input) 13 | { 14 | memcpy(Buffer, &input, sizeof(input)); 15 | return sizeof(input); 16 | } 17 | static size_t deserialize(char* Buffer, Type& output) 18 | { 19 | memcpy(&output, Buffer, sizeof(output)); 20 | return sizeof(output); 21 | } 22 | }; 23 | #endif // !SERIALIZE_H 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /TCP/StepByStep/E03/Client/Source.cpp: -------------------------------------------------------------------------------- 1 | #include "ClientConnection.h" 2 | #include 3 | #include 4 | #include "Serialize.h" 5 | #include 6 | #include "Queue.h" 7 | ClientConnection tcpConnection; 8 | std::mutex ClientLiatDoor; 9 | std::mutex QueueListDoor; 10 | std::map QueueList; 11 | 12 | void Client(bool flag) 13 | { 14 | 15 | } 16 | void __stdcall changeprogress(int queueid, int i) 17 | { 18 | QueueListDoor.lock(); 19 | if (i == 100) 20 | { 21 | QueueList.erase(queueid); 22 | } 23 | QueueListDoor.unlock(); 24 | clog << i << " % " << endl; 25 | } 26 | void StartDownload(int socketid, int queueid) 27 | { 28 | StartPacket sp; 29 | sp.header = Header::start; 30 | sp.QueueID = queueid; 31 | char Buffer[sizeof(StartPacket)]; 32 | memset(Buffer, 0, sizeof(StartPacket)); 33 | Serialize::serialize(Buffer, sp); 34 | send(socketid, Buffer, sizeof(StartPacket), 0); 35 | } 36 | 37 | void Reciev(char* buffer, int size) 38 | { 39 | Packet pk; 40 | Serialize::deserialize(buffer, pk); 41 | switch (pk.header) 42 | { 43 | case Header::message: 44 | { 45 | MessagePacket msp; 46 | Serialize::deserialize(buffer, msp); 47 | string username; 48 | 49 | cout << "\nServer : " << string(msp.Buffer, msp.size) << endl; 50 | } 51 | break; 52 | case Header::queue: 53 | { 54 | QueuePacket qp; 55 | Serialize::deserialize(buffer, qp); 56 | Queue* item = Queue::Download(tcpConnection.MySocket, qp.QueueID, qp.FileName, qp.FileExtention, qp.Size, changeprogress); 57 | QueueListDoor.lock(); 58 | QueueList.insert(std::pair(qp.QueueID, item)); 59 | QueueListDoor.unlock(); 60 | StartDownload(tcpConnection.MySocket, qp.QueueID); 61 | } 62 | break; 63 | case Header::start: 64 | { 65 | StartPacket sp; 66 | Serialize::deserialize(buffer, sp); 67 | QueueListDoor.lock(); 68 | auto item = QueueList.find(sp.QueueID); 69 | if (item != QueueList.end()) 70 | { 71 | item->second->Start(); 72 | } 73 | QueueListDoor.unlock(); 74 | } 75 | break; 76 | case Header::chunck: 77 | { 78 | FilePacket fp; 79 | Serialize::deserialize(buffer, fp); 80 | QueueListDoor.lock(); 81 | auto item = QueueList.find(fp.QueueId); 82 | Queue* queue = nullptr; 83 | if (item != QueueList.end()) 84 | queue = item->second; 85 | QueueListDoor.unlock(); 86 | queue->Write(fp.Buffer, fp.Read); 87 | } 88 | break; 89 | default: 90 | break; 91 | } 92 | } 93 | 94 | void sendmessage() 95 | { 96 | while (!tcpConnection.IsRunning); 97 | cout << "Enter your Message : "; 98 | string message; 99 | getline(cin, message); 100 | 101 | // Packting 102 | MessagePacket msp; 103 | msp.header = Header::message; 104 | msp.size = message.length(); 105 | memcpy(msp.Buffer, message.c_str(), msp.size); 106 | 107 | string username; 108 | 109 | char BUFFER[SIZE_Message]; 110 | memset(BUFFER, 0, SIZE_Message); 111 | Serialize::serialize(BUFFER, msp); 112 | 113 | send(tcpConnection.MySocket, BUFFER, SIZE_Message, 0); 114 | } 115 | void SendFile(string path) 116 | { 117 | 118 | QueueListDoor.lock(); 119 | int id; 120 | do 121 | { 122 | id = rand() % 9000 + 1000; 123 | } 124 | while (QueueList.find(id) != QueueList.end()); 125 | Queue* item = Queue::Upload(tcpConnection.MySocket, path, id, changeprogress); 126 | QueueList.insert(std::pair(id, item)); 127 | QueueListDoor.unlock(); 128 | 129 | QueuePacket qp; 130 | qp.header = Header::queue; 131 | memcpy(qp.FileExtention, item->FileExtention.c_str(), item->FileExtention.size()); 132 | memcpy(qp.FileName, item->FileName.c_str(), item->FileName.size()); 133 | qp.QueueID = id; 134 | qp.Size = item->Length; 135 | const int size = sizeof(QueuePacket); 136 | char Buffer[size]; 137 | memset(Buffer, 0, size); 138 | Serialize< QueuePacket>::serialize(Buffer, qp); 139 | send(tcpConnection.MySocket, Buffer, size, 0); 140 | } 141 | int main() 142 | { 143 | tcpConnection = ClientConnection("127.0.0.1", 7071, Client, Reciev); 144 | if (tcpConnection.Init()) 145 | { 146 | thread ConnectionThread = thread([&]() {tcpConnection.Start(); }); 147 | thread SendThread = thread([&]() { 148 | while (!tcpConnection.IsRunning); 149 | string path; 150 | cout << "Enter Path : "; 151 | getline(cin, path); 152 | SendFile(path); 153 | }); 154 | ConnectionThread.join(); 155 | SendThread.join(); 156 | } 157 | else 158 | { 159 | return 0; 160 | } 161 | } -------------------------------------------------------------------------------- /TCP/StepByStep/E03/Server/FileHandler.h: -------------------------------------------------------------------------------- 1 | #ifndef FILEHANDLER_H 2 | #define FILEHANDLER_H 3 | #include 4 | #include 5 | using std::string; 6 | using std::ifstream; 7 | class FileHandler 8 | { 9 | public: 10 | static string GetFileName(string path) 11 | { 12 | for (int i = path.length(); i >= 0; i--) 13 | if (path[i] == '\\') 14 | return path.substr(i + 1); 15 | return path; 16 | } 17 | static string GetFileExtention(string path) 18 | { 19 | string filename = GetFileName(path); 20 | size_t i = filename.rfind('.', filename.length()); 21 | if (i != string::npos) { 22 | return(filename.substr(i, filename.length() - i)); 23 | } 24 | } 25 | static string GetFileNameWhitOutExtention(string path) 26 | { 27 | string filename = GetFileName(path); 28 | size_t i = filename.rfind('.', filename.length()); 29 | if (i != string::npos) { 30 | return(filename.substr(0, i)); 31 | } 32 | } 33 | static inline string Combine(string str1, string str2) 34 | { 35 | return str1 + "\\" + str2; 36 | } 37 | static inline string TempPath(string Filename, string Extention = ".tmp") 38 | { 39 | while (IsFileExist(Filename + Extention)) 40 | Filename += "_copy"; 41 | return Filename + Extention; 42 | 43 | } 44 | static inline bool IsFileExist(const string& name) { 45 | ifstream f(name.c_str()); 46 | return f.good(); 47 | } 48 | static bool ConvertTmpToStableFile(const string& tmppath, const string& destinationpath) 49 | { 50 | string fname; 51 | if (GetFileNameWhitOutExtention(destinationpath) != "") 52 | fname = GetFileNameWhitOutExtention(destinationpath) + GetFileExtention(destinationpath); 53 | else 54 | fname = GetFileNameWhitOutExtention(tmppath) + GetFileExtention(destinationpath); 55 | 56 | if (!IsFileExist(tmppath)) 57 | return 0; 58 | 59 | if (rename(tmppath.c_str(), fname.c_str()) != 0) 60 | ConvertTmpToStableFile(tmppath, GetFileNameWhitOutExtention(fname) + "_Copy" + GetFileExtention(destinationpath)); 61 | else 62 | return 1; 63 | } 64 | }; 65 | #endif -------------------------------------------------------------------------------- /TCP/StepByStep/E03/Server/Packets.h: -------------------------------------------------------------------------------- 1 | #ifndef PACKET_H 2 | #define PACKET_H 3 | #define SIZE_Buffer (20*1024) 4 | #define SIZE_FileBuffer (SIZE_Buffer-12)-1 5 | #define SIZE_Message 1024 6 | #define SIZE_MessageBuffer SIZE_Message-8-1 7 | 8 | enum Header : char 9 | { 10 | queue, 11 | start, 12 | chunck, 13 | message 14 | }; 15 | struct Packet 16 | { 17 | Header header; 18 | }; 19 | struct StartPacket : public Packet 20 | { 21 | int QueueID; 22 | }; 23 | struct QueuePacket : public Packet 24 | { 25 | char FileName[165]; 26 | char FileExtention[205]; 27 | long Size; 28 | int QueueID; 29 | QueuePacket() 30 | { 31 | memset(FileName, 0, 165); 32 | memset(FileExtention, 0, 205); 33 | } 34 | }; 35 | struct FilePacket : public Packet 36 | { 37 | int QueueId; 38 | int Read; 39 | char Buffer[SIZE_FileBuffer]; 40 | FilePacket() 41 | { 42 | memset(Buffer, 0, SIZE_FileBuffer); 43 | } 44 | 45 | }; 46 | struct MessagePacket : public Packet 47 | { 48 | int size; 49 | char Buffer[SIZE_MessageBuffer]; 50 | MessagePacket() 51 | { 52 | memset(Buffer, 0, SIZE_MessageBuffer); 53 | } 54 | }; 55 | #endif // !PACKET_H 56 | -------------------------------------------------------------------------------- /TCP/StepByStep/E03/Server/Queue.cpp: -------------------------------------------------------------------------------- 1 | #include "Queue.h" 2 | 3 | Queue* Queue::Upload(int socketid, string path, int QueueID , ChanheProgress chanheprogress) 4 | { 5 | try 6 | { 7 | Queue* item = new Queue(); 8 | item->QueueID = QueueID; 9 | item->chanheprogress = chanheprogress; 10 | item->SocketID = socketid; 11 | item->FileName = FileHandler::GetFileNameWhitOutExtention(path); 12 | item->FileExtention = FileHandler::GetFileExtention(path); 13 | item->FilePath = path; 14 | item->Index = 0; 15 | item->Treansfered = 0; 16 | item->Progress = 0; 17 | item->LastProgress = 0; 18 | item->Type = QueueTYPE::upload; 19 | item->readfile = std::ifstream(path, std::ios::binary); 20 | if (!item->readfile.is_open()) 21 | return nullptr; 22 | item->Lenght = item->readfile.seekg(0, std::ios::end).tellg(); 23 | item->readfile.seekg(0); 24 | return item; 25 | 26 | } 27 | catch (...) 28 | { 29 | return nullptr; 30 | } 31 | } 32 | Queue* Queue::Download(int socketid,int QueueID, string FileName, string FileExtention, long size, ChanheProgress chanheprogress) 33 | { 34 | try 35 | { 36 | Queue* item = new Queue(); 37 | item->QueueID = QueueID; 38 | item->chanheprogress = chanheprogress; 39 | item->SocketID = socketid; 40 | item->FileName = FileName; 41 | item->FileExtention = FileExtention; 42 | item->FilePath = FileHandler::Combine(".", FileHandler::TempPath(FileName)); 43 | item->Index = 0; 44 | item->Treansfered = 0; 45 | item->Progress = 0; 46 | item->LastProgress = 0; 47 | item->Type = QueueTYPE::download; 48 | item->writefile = std::ofstream(item->FilePath, std::ios::binary); 49 | if (!item->writefile.is_open()) 50 | return nullptr; 51 | item->Lenght = size; 52 | return item; 53 | } 54 | catch (...) 55 | { 56 | return nullptr; 57 | } 58 | } 59 | void Queue::SetProgress(int read) 60 | { 61 | this->Index += read; 62 | this->Treansfered += read; 63 | this->Progress = (int)((this->Treansfered * 100) / this->Lenght); 64 | if (this->LastProgress < this->Progress) 65 | this->LastProgress = this->Progress; 66 | if (this->LastProgress == 100) 67 | this->Close(); 68 | if (chanheprogress != NULL) 69 | chanheprogress(this->QueueID, this->LastProgress); 70 | } 71 | void Queue::Start() 72 | { 73 | this->Running = true; 74 | this->SendThread = thread([&]() {TrenasferProc(this); }); 75 | } 76 | void Queue::Close() 77 | { 78 | if (this->Type == QueueTYPE::download) 79 | { 80 | this->writefile.close(); 81 | FileHandler::ConvertTmpToStableFile(this->FilePath , this->FileExtention); 82 | } 83 | else if (this->Type == QueueTYPE::upload) 84 | { 85 | this->readfile.close(); 86 | this->Running = false; 87 | this->SendThread.detach(); 88 | } 89 | } 90 | void Queue::Write(const char const* Buffer, int Read) 91 | { 92 | 93 | if (this->writefile.is_open()) 94 | { 95 | this->writefile.write(Buffer, Read); 96 | SetProgress(Read); 97 | } 98 | } 99 | void Queue::TrenasferProc(Queue* item) 100 | { 101 | while (item->Running && item->Index < item->Lenght) 102 | { 103 | sendDoor.lock(); 104 | 105 | long read = (item->Lenght - item->Index < SIZE_FileBuffer) ? item->Lenght - item->Index : SIZE_FileBuffer; 106 | 107 | FilePacket fp; 108 | fp.header = Header::chunck; 109 | fp.QueueId = item->QueueID; 110 | fp.Read = read; 111 | item->readfile.read(fp.Buffer, read); 112 | 113 | char Buffer[SIZE_Buffer]; 114 | memset(Buffer, 0, SIZE_Buffer); 115 | int size = Serialize< FilePacket>::serialize(Buffer, fp); 116 | send(this->SocketID, Buffer, size, 0); 117 | SetProgress(read); 118 | sendDoor.unlock(); 119 | std::this_thread::sleep_for(std::chrono::microseconds(5)); 120 | } 121 | } 122 | Queue::Queue() 123 | { 124 | 125 | } -------------------------------------------------------------------------------- /TCP/StepByStep/E03/Server/Queue.h: -------------------------------------------------------------------------------- 1 | #ifndef QUEUE_H 2 | #define QUEUE_H 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "FileHandler.h" 9 | #include "Packets.h" 10 | #include "Serialize.h" 11 | #include "TCPListener.h" 12 | using namespace std; 13 | 14 | typedef void (__stdcall *ChanheProgress)(int Queueid , int value); 15 | enum QueueTYPE 16 | { 17 | download, 18 | upload 19 | }; 20 | 21 | class Queue 22 | { 23 | private: 24 | 25 | Queue(); 26 | void TrenasferProc(Queue*); 27 | string FilePath; 28 | thread SendThread; 29 | mutex sendDoor; 30 | ifstream readfile; 31 | ofstream writefile; 32 | long Treansfered; 33 | long Index; 34 | int Progress, LastProgress; 35 | bool Running; 36 | int SocketID; 37 | ChanheProgress chanheprogress; 38 | public: 39 | string FileName; 40 | string FileExtention; 41 | long Lenght; 42 | int QueueID; 43 | QueueTYPE Type; 44 | static Queue* Upload(int socketid , string path , int QueueID , ChanheProgress chanheprogress); 45 | static Queue* Download(int socketid , int QueueID, string FileName , string FileExtention , long size, ChanheProgress chanheprogress); 46 | void SetProgress(int read); 47 | void Start(); 48 | void Close(); 49 | void Write(const char const* Buffer , int Read); 50 | 51 | }; 52 | #endif // !QUEUE_H 53 | -------------------------------------------------------------------------------- /TCP/StepByStep/E03/Server/Serialize.h: -------------------------------------------------------------------------------- 1 | #ifndef SERIALIZE_H 2 | #define SERIALIZE_H 3 | #include 4 | template 5 | class Serialize 6 | { 7 | public: 8 | static size_t size(const Type input) 9 | { 10 | return sizeof(input); 11 | } 12 | static size_t serialize(char* const Buffer , Type input) 13 | { 14 | memcpy(Buffer, &input, sizeof(input)); 15 | return sizeof(input); 16 | } 17 | static size_t deserialize(char* Buffer, Type& output) 18 | { 19 | memcpy(&output, Buffer, sizeof(output)); 20 | return sizeof(output); 21 | } 22 | }; 23 | #endif // !SERIALIZE_H 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /TCP/StepByStep/E03/Server/Source.cpp: -------------------------------------------------------------------------------- 1 | #include "TCPListener.h" 2 | #include "Serialize.h" 3 | #include 4 | #include 5 | #include 6 | #include "Queue.h" 7 | map ClientList; 8 | static int ClientNum = 0; 9 | TCPListener tcpServer; 10 | std::mutex ClientLiatDoor; 11 | std::mutex QueueListDoor; 12 | std::map Queue_List; 13 | 14 | void Client(int Socketid , bool flag) 15 | { 16 | std::lock_guardDoor(ClientLiatDoor); 17 | std::clog << "\nNew Connect\n"; 18 | if (flag) 19 | { 20 | ClientList.insert(pair("Amirreza" + to_string(ClientNum++), Socketid)); 21 | } 22 | else 23 | { 24 | string username; 25 | for (auto target : ClientList) 26 | { 27 | if (target.second == Socketid) 28 | { 29 | username = target.first; 30 | break; 31 | } 32 | } 33 | ClientList.erase(username); 34 | } 35 | } 36 | void __stdcall changeprogress(int queueid , int i ) 37 | { 38 | QueueListDoor.lock(); 39 | if (i == 100) 40 | { 41 | Queue_List.erase(queueid); 42 | } 43 | QueueListDoor.unlock(); 44 | } 45 | void StartDownload(int socketid , int queueid) 46 | { 47 | StartPacket sp; 48 | sp.header = Header::start; 49 | sp.QueueID = queueid; 50 | char Buffer[sizeof(StartPacket)]; 51 | memset(Buffer, 0, sizeof(StartPacket)); 52 | Serialize::serialize(Buffer, sp); 53 | send(socketid , Buffer , sizeof(StartPacket) , 0); 54 | } 55 | 56 | void Reciev(int socketid , char* buffer , int size) 57 | { 58 | Packet pk; 59 | Serialize::deserialize(buffer, pk); 60 | switch (pk.header) 61 | { 62 | case Header::message: 63 | { 64 | MessagePacket msp; 65 | Serialize::deserialize(buffer, msp); 66 | string username; 67 | for (auto target : ClientList) 68 | { 69 | if (target.second == socketid) 70 | { 71 | username = target.first; 72 | break; 73 | } 74 | } 75 | cout << username << string(msp.Buffer, msp.size) << endl; 76 | } 77 | break; 78 | case Header::queue: 79 | { 80 | QueuePacket qp; 81 | Serialize::deserialize(buffer, qp); 82 | Queue* item = Queue::Download(socketid, qp.QueueID, qp.FileName, qp.FileExtention, qp.Size, changeprogress); 83 | QueueListDoor.lock(); 84 | Queue_List.insert(std::pair(qp.QueueID, item)); 85 | QueueListDoor.unlock(); 86 | StartDownload(socketid , qp.QueueID); 87 | } 88 | break; 89 | case Header::start: 90 | { 91 | StartPacket sp; 92 | Serialize::deserialize(buffer, sp); 93 | QueueListDoor.lock(); 94 | auto item = Queue_List.find(sp.QueueID); 95 | if (item != Queue_List.end()) 96 | { 97 | item->second->Start(); 98 | } 99 | QueueListDoor.unlock(); 100 | } 101 | break; 102 | case Header::chunck: 103 | { 104 | FilePacket fp; 105 | Serialize::deserialize(buffer, fp); 106 | QueueListDoor.lock(); 107 | auto item = Queue_List.find(fp.QueueId); 108 | Queue* queue = nullptr; 109 | if (item != Queue_List.end()) 110 | queue = item->second; 111 | QueueListDoor.unlock(); 112 | queue->Write(fp.Buffer, fp.Read); 113 | } 114 | break; 115 | default: 116 | break; 117 | } 118 | } 119 | 120 | void sendmessage() 121 | { 122 | while (!tcpServer.IsRunning); 123 | 124 | cout << "\nEnter your Message : "; 125 | string message; 126 | getline(cin, message); 127 | 128 | // Packting 129 | MessagePacket msp; 130 | msp.header = Header::message; 131 | msp.size = message.length(); 132 | memcpy(msp.Buffer, message.c_str(), msp.size); 133 | 134 | string username; 135 | ClientLiatDoor.lock(); 136 | do 137 | { 138 | cout << "Enter UserName : "; 139 | getline(cin, username); 140 | } while (ClientList.find(username) == ClientList.end()); 141 | int ClinetID = ClientList.find(username)->second; 142 | ClientLiatDoor.unlock(); 143 | 144 | char BUFFER[SIZE_Message]; 145 | memset(BUFFER, 0, SIZE_Message); 146 | Serialize::serialize(BUFFER, msp); 147 | 148 | send(ClinetID, BUFFER, SIZE_Message, 0); 149 | } 150 | void SendFile(string path) 151 | { 152 | string username; 153 | ClientLiatDoor.lock(); 154 | do 155 | { 156 | cout << "Enter UserName : "; 157 | getline(cin, username); 158 | } while (ClientList.find(username) == ClientList.end()); 159 | int ClinetID = ClientList.find(username)->second; 160 | ClientLiatDoor.unlock(); 161 | QueueListDoor.lock(); 162 | int id; 163 | do 164 | { 165 | id = rand() % 9000 + 1000; 166 | } while (Queue_List.find(id) != Queue_List.end()); 167 | Queue* item = Queue::Upload(ClinetID, path, id, changeprogress); 168 | Queue_List.insert(std::pair(id, item)); 169 | QueueListDoor.unlock(); 170 | 171 | QueuePacket qp; 172 | qp.header = Header::queue; 173 | memcpy(qp.FileExtention, item->FileExtention.c_str(), item->FileExtention.size()); 174 | memcpy(qp.FileName, item->FileName.c_str(), item->FileName.size()); 175 | qp.QueueID = id; 176 | qp.Size = item->Lenght; 177 | const int size = sizeof(QueuePacket); 178 | char Buffer[size]; 179 | memset(Buffer , 0 , size); 180 | Serialize< QueuePacket>::serialize(Buffer, qp); 181 | send(ClinetID , Buffer , size ,0); 182 | } 183 | int main() 184 | { 185 | tcpServer = TCPListener("127.0.0.1", 7071, Client, Reciev); 186 | if (tcpServer.Init()) 187 | { 188 | thread ConnectionThread = thread([&]() {tcpServer.Start();}); 189 | thread SendThread = thread([&]() { 190 | while (!tcpServer.IsRunning); 191 | string path; 192 | cout << "Enter Path : "; 193 | getline ( cin, path); 194 | SendFile(path); 195 | }); 196 | ConnectionThread.join(); 197 | SendThread.join(); 198 | } 199 | else 200 | { 201 | return 0; 202 | } 203 | } -------------------------------------------------------------------------------- /TCP/StepByStep/E03/Server/TCPListener.cpp: -------------------------------------------------------------------------------- 1 | #include "TCPListener.h" 2 | TCPListener::TCPListener() 3 | { 4 | 5 | } 6 | TCPListener::TCPListener(string ip, int port, Client_Handler clientHandler, Recive_Handler reciveHandler) 7 | : ip(ip) , port(port) , clientHandler(clientHandler) , reciveHandler(reciveHandler) 8 | { 9 | 10 | } 11 | bool TCPListener::Init() 12 | { 13 | WSADATA WindowsSocketInof; 14 | WORD Version = MAKEWORD(2, 2); 15 | int res = WSAStartup(Version , &WindowsSocketInof); 16 | return res == 0; 17 | } 18 | void TCPListener::Start() 19 | { 20 | Server = CreateSocket(); 21 | if (Server != INVALID_SOCKET) 22 | { 23 | IsRunning = true; 24 | FD_ZERO(&master); 25 | FD_ZERO(&Read); 26 | FD_SET(Server, &master); 27 | Read = master; 28 | while (true) 29 | Run(); 30 | } 31 | else 32 | { 33 | throw exception("Start Function : Server Connection Failed!"); 34 | } 35 | } 36 | void TCPListener::CleanUp() 37 | { 38 | IsRunning = false; 39 | closesocket(Server); 40 | WSACleanup(); 41 | } 42 | TCPListener::~TCPListener() 43 | { 44 | CleanUp(); 45 | } 46 | void TCPListener::Run() 47 | { 48 | Read = master; 49 | int SocketCount = select(0, &Read, nullptr, nullptr, nullptr); 50 | if (SocketCount <= 0) 51 | { 52 | CleanUp(); 53 | throw exception("Run Function : Server Connection Failed!"); 54 | } 55 | else 56 | { 57 | for (int i = 0; i < SocketCount; i++) 58 | { 59 | SOCKET SelectedSocket = Read.fd_array[i]; 60 | if (SelectedSocket == Server) 61 | { 62 | SOCKET NewClient = accept(Server, nullptr, nullptr); 63 | FD_SET(NewClient, &master); 64 | clientHandler(NewClient, true); 65 | } 66 | else 67 | { 68 | char BUFFER[SIZE_Buffer]; 69 | memset(BUFFER, 0, SIZE_Buffer); 70 | int ByteRecv = recv(SelectedSocket, BUFFER, SIZE_Buffer, 0); 71 | if (ByteRecv <= 0) 72 | { 73 | FD_CLR(SelectedSocket , &master); 74 | clientHandler(SelectedSocket, false); 75 | } 76 | else 77 | { 78 | if (ByteRecv >= 1) 79 | reciveHandler(SelectedSocket, BUFFER, ByteRecv); 80 | } 81 | } 82 | } 83 | } 84 | } 85 | SOCKET TCPListener::CreateSocket() 86 | { 87 | SOCKET Server = socket(AF_INET, SOCK_STREAM, 0); 88 | if (Server != INVALID_SOCKET) 89 | { 90 | sockaddr_in ServerAddress; 91 | ServerAddress.sin_family = AF_INET; // IP v4 92 | ServerAddress.sin_port = htons(port); 93 | ServerAddress.sin_addr.S_un.S_addr = INADDR_ANY; 94 | int res = ::bind(Server , (sockaddr*)&ServerAddress , sizeof(ServerAddress)); 95 | if (res != SOCKET_ERROR) 96 | { 97 | res = listen(Server, SOMAXCONN); 98 | if (res != SOCKET_ERROR) 99 | { 100 | return Server; 101 | } 102 | else 103 | { 104 | closesocket(Server); 105 | CleanUp(); 106 | return -1; 107 | } 108 | } 109 | else 110 | { 111 | closesocket(Server); 112 | CleanUp(); 113 | return -1; 114 | } 115 | } 116 | else 117 | { 118 | closesocket(Server); 119 | CleanUp(); 120 | return -1; 121 | } 122 | } -------------------------------------------------------------------------------- /TCP/StepByStep/E03/Server/TCPListener.h: -------------------------------------------------------------------------------- 1 | #ifndef TCPListener_H 2 | #define TCPListener_H 3 | #include 4 | #include 5 | #include "Packets.h" 6 | #include 7 | 8 | #pragma comment (lib , "Ws2_32.lib") 9 | using namespace std; 10 | typedef void (*Client_Handler)(int SocketID, bool flag); 11 | typedef void (*Recive_Handler)(int SockerID, char* Buffer, int DataLegth); 12 | 13 | class TCPListener 14 | { 15 | public: 16 | bool IsRunning; 17 | TCPListener(); 18 | TCPListener(string ip, int port, Client_Handler , Recive_Handler); 19 | bool Init(); 20 | void Start(); 21 | void CleanUp(); 22 | ~TCPListener(); 23 | private: 24 | fd_set master; 25 | fd_set Read; 26 | Client_Handler clientHandler; 27 | Recive_Handler reciveHandler; 28 | string ip; 29 | SOCKET Server; 30 | int port; 31 | void Run(); 32 | SOCKET CreateSocket(); 33 | }; 34 | #endif // !TCPListener_H 35 | -------------------------------------------------------------------------------- /TCP/StepByStep/E04-Final/Cleint/Cleint.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.31205.134 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Cleint", "Cleint.vcxproj", "{89B79D75-432E-42CF-AC37-468C87391FEF}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {89B79D75-432E-42CF-AC37-468C87391FEF}.Debug|x64.ActiveCfg = Debug|x64 17 | {89B79D75-432E-42CF-AC37-468C87391FEF}.Debug|x64.Build.0 = Debug|x64 18 | {89B79D75-432E-42CF-AC37-468C87391FEF}.Debug|x86.ActiveCfg = Debug|Win32 19 | {89B79D75-432E-42CF-AC37-468C87391FEF}.Debug|x86.Build.0 = Debug|Win32 20 | {89B79D75-432E-42CF-AC37-468C87391FEF}.Release|x64.ActiveCfg = Release|x64 21 | {89B79D75-432E-42CF-AC37-468C87391FEF}.Release|x64.Build.0 = Release|x64 22 | {89B79D75-432E-42CF-AC37-468C87391FEF}.Release|x86.ActiveCfg = Release|Win32 23 | {89B79D75-432E-42CF-AC37-468C87391FEF}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {3C6AAE74-7F81-44D4-BA37-955B8AC6A981} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /TCP/StepByStep/E04-Final/Cleint/Cleint.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 16.0 23 | Win32Proj 24 | {89b79d75-432e-42cf-ac37-468c87391fef} 25 | Cleint 26 | 10.0 27 | 28 | 29 | 30 | Application 31 | true 32 | v142 33 | Unicode 34 | 35 | 36 | Application 37 | false 38 | v142 39 | true 40 | Unicode 41 | 42 | 43 | Application 44 | true 45 | v142 46 | Unicode 47 | 48 | 49 | Application 50 | false 51 | v142 52 | true 53 | Unicode 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | true 75 | 76 | 77 | false 78 | 79 | 80 | true 81 | 82 | 83 | false 84 | 85 | 86 | 87 | Level3 88 | true 89 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 90 | true 91 | 92 | 93 | Console 94 | true 95 | 96 | 97 | 98 | 99 | Level3 100 | true 101 | true 102 | true 103 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 104 | true 105 | 106 | 107 | Console 108 | true 109 | true 110 | true 111 | 112 | 113 | 114 | 115 | Level3 116 | true 117 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 118 | true 119 | 120 | 121 | Console 122 | true 123 | 124 | 125 | 126 | 127 | Level3 128 | true 129 | true 130 | true 131 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 132 | true 133 | 134 | 135 | Console 136 | true 137 | true 138 | true 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | -------------------------------------------------------------------------------- /TCP/StepByStep/E04-Final/Cleint/Cleint.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Header Files 20 | 21 | 22 | Header Files 23 | 24 | 25 | Header Files 26 | 27 | 28 | Header Files 29 | 30 | 31 | Header Files 32 | 33 | 34 | 35 | 36 | Source Files 37 | 38 | 39 | Source Files 40 | 41 | 42 | Source Files 43 | 44 | 45 | Source Files 46 | 47 | 48 | -------------------------------------------------------------------------------- /TCP/StepByStep/E04-Final/Cleint/Cleint.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /TCP/StepByStep/E04-Final/Cleint/CleintConnection.cpp: -------------------------------------------------------------------------------- 1 | #include "CleintConnection.h" 2 | 3 | CleintConnection::CleintConnection() 4 | { 5 | 6 | } 7 | CleintConnection::CleintConnection(string ip, int port, Connection_Handler clientHandler, Recive_Handler reciveHandler) 8 | : Serverip(ip), Serverport(port), connectionHandler(clientHandler), reciveHandler(reciveHandler) 9 | { 10 | 11 | } 12 | bool CleintConnection::Init() 13 | { 14 | WSADATA WindowsSocketInof; 15 | WORD Version = MAKEWORD(2, 2); 16 | int res = WSAStartup(Version, &WindowsSocketInof); 17 | return res == 0; 18 | } 19 | void CleintConnection::Start() 20 | { 21 | MySocket = CreateSocket(); 22 | if (MySocket != INVALID_SOCKET) 23 | { 24 | IsRunning = true; 25 | connectionHandler(true); 26 | while (true) 27 | Run(); 28 | } 29 | else 30 | { 31 | throw exception("Start Function : Server Connection Failed!"); 32 | } 33 | } 34 | void CleintConnection::CleanUp() 35 | { 36 | IsRunning = false; 37 | closesocket(MySocket); 38 | WSACleanup(); 39 | } 40 | CleintConnection::~CleintConnection() 41 | { 42 | CleanUp(); 43 | } 44 | void CleintConnection::Run() 45 | { 46 | char BUFFER[SIZE_Buffer]; 47 | memset(BUFFER, 0, SIZE_Buffer); 48 | int ByteRecv = recv(MySocket, BUFFER, SIZE_Buffer, 0); 49 | if (ByteRecv <= 0) 50 | { 51 | connectionHandler( false); 52 | } 53 | else 54 | { 55 | if (ByteRecv >= 1) 56 | reciveHandler(BUFFER, ByteRecv); 57 | } 58 | } 59 | SOCKET CleintConnection::CreateSocket() 60 | { 61 | SOCKET MySocket = socket(AF_INET, SOCK_STREAM, 0); 62 | if (MySocket != INVALID_SOCKET) 63 | { 64 | sockaddr_in ServerAddress; 65 | ServerAddress.sin_family = AF_INET; // IP v4 66 | ServerAddress.sin_port = htons(Serverport); 67 | ServerAddress.sin_addr.S_un.S_addr = INADDR_ANY; 68 | int res = inet_pton(AF_INET, Serverip.c_str(), &ServerAddress.sin_addr); 69 | if (res <= 0) 70 | { 71 | CleanUp(); 72 | } 73 | else 74 | { 75 | res = connect(MySocket, (sockaddr*)&ServerAddress, sizeof(ServerAddress)); 76 | if (res != SOCKET_ERROR) 77 | { 78 | return MySocket; 79 | } 80 | else 81 | { 82 | closesocket(MySocket); 83 | CleanUp(); 84 | return -1; 85 | } 86 | } 87 | } 88 | else 89 | { 90 | closesocket(MySocket); 91 | CleanUp(); 92 | return -1; 93 | } 94 | } -------------------------------------------------------------------------------- /TCP/StepByStep/E04-Final/Cleint/CleintConnection.h: -------------------------------------------------------------------------------- 1 | #ifndef CLINETCONNECTION_H 2 | #define CLINETCONNECTION_H 3 | #include 4 | #include 5 | #include "Packets.h" 6 | #pragma comment (lib , "Ws2_32.lib") 7 | using namespace std; 8 | typedef void (*Connection_Handler)(bool flag); 9 | typedef void (*Recive_Handler)(char* Buffer, int DataLegth); 10 | 11 | class CleintConnection 12 | { 13 | public: 14 | bool IsRunning; 15 | SOCKET MySocket; 16 | CleintConnection(); 17 | CleintConnection(string ip, int port, Connection_Handler, Recive_Handler); 18 | bool Init(); 19 | void Start(); 20 | void CleanUp(); 21 | ~CleintConnection(); 22 | private: 23 | 24 | Connection_Handler connectionHandler; 25 | Recive_Handler reciveHandler; 26 | string Serverip; 27 | int Serverport; 28 | void Run(); 29 | SOCKET CreateSocket(); 30 | 31 | }; 32 | 33 | 34 | #endif // !CLINETCONNECTION_H 35 | 36 | 37 | -------------------------------------------------------------------------------- /TCP/StepByStep/E04-Final/Cleint/FileHandler.h: -------------------------------------------------------------------------------- 1 | #ifndef FILEHANDLER_H 2 | #define FILEHANDLER_H 3 | #include 4 | #include 5 | using std::string; 6 | using std::ifstream; 7 | class FileHandler 8 | { 9 | public: 10 | static string GetFileName(string path) 11 | { 12 | for (int i = path.length(); i >= 0; i--) 13 | if (path[i] == '\\') 14 | return path.substr(i + 1); 15 | return path; 16 | } 17 | static string GetFileExtention(string path) 18 | { 19 | string filename = GetFileName(path); 20 | size_t i = filename.rfind('.', filename.length()); 21 | if (i != string::npos) { 22 | return(filename.substr(i, filename.length() - i)); 23 | } 24 | } 25 | static string GetFileNameWhitOutExtention(string path) 26 | { 27 | string filename = GetFileName(path); 28 | size_t i = filename.rfind('.', filename.length()); 29 | if (i != string::npos) { 30 | return(filename.substr(0, i)); 31 | } 32 | } 33 | static inline string Combine(string str1, string str2) 34 | { 35 | return str1 + "\\" + str2; 36 | } 37 | static inline string TempPath(string Filename, string Extention = ".tmp") 38 | { 39 | while (IsFileExist(Filename + Extention)) 40 | Filename += "_copy"; 41 | return Filename + Extention; 42 | 43 | } 44 | static inline bool IsFileExist(const string& name) { 45 | ifstream f(name.c_str()); 46 | return f.good(); 47 | } 48 | static bool ConvertTmpToStableFile(const string& tmppath, const string& destinationpath) 49 | { 50 | string fname; 51 | if (GetFileNameWhitOutExtention(destinationpath) != "") 52 | fname = GetFileNameWhitOutExtention(destinationpath) + GetFileExtention(destinationpath); 53 | else 54 | fname = GetFileNameWhitOutExtention(tmppath) + GetFileExtention(destinationpath); 55 | 56 | if (!IsFileExist(tmppath)) 57 | return 0; 58 | 59 | if (rename(tmppath.c_str(), fname.c_str()) != 0) 60 | ConvertTmpToStableFile(tmppath, GetFileNameWhitOutExtention(fname) + "_Copy" + GetFileExtention(destinationpath)); 61 | else 62 | return 1; 63 | } 64 | }; 65 | #endif -------------------------------------------------------------------------------- /TCP/StepByStep/E04-Final/Cleint/Packets.h: -------------------------------------------------------------------------------- 1 | #ifndef PACKET_H 2 | #define PACKET_H 3 | #define SIZE_Buffer (20*1024) 4 | #define SIZE_FileBuffer (SIZE_Buffer-12)-1 5 | #define SIZE_Message 1024 6 | #define SIZE_MessageBuffer SIZE_Message-8-1 7 | 8 | enum Header : char 9 | { 10 | queue, 11 | start, 12 | chunck, 13 | message 14 | }; 15 | struct Packet 16 | { 17 | Header header; 18 | }; 19 | struct StartPacket : public Packet 20 | { 21 | int QueueID; 22 | }; 23 | struct QueuePacket : public Packet 24 | { 25 | char FileName[165]; 26 | char FileExtention[205]; 27 | long Size; 28 | int QueueID; 29 | QueuePacket() 30 | { 31 | memset(FileName, 0, 165); 32 | memset(FileExtention, 0, 205); 33 | } 34 | }; 35 | struct FilePacket : public Packet 36 | { 37 | int QueueId; 38 | int Read; 39 | char Buffer[SIZE_FileBuffer]; 40 | FilePacket() 41 | { 42 | memset(Buffer, 0, SIZE_FileBuffer); 43 | } 44 | 45 | }; 46 | struct MessagePacket : public Packet 47 | { 48 | int size; 49 | char Buffer[SIZE_MessageBuffer]; 50 | MessagePacket() 51 | { 52 | memset(Buffer, 0, SIZE_MessageBuffer); 53 | } 54 | }; 55 | #endif // !PACKET_H 56 | -------------------------------------------------------------------------------- /TCP/StepByStep/E04-Final/Cleint/Queue.cpp: -------------------------------------------------------------------------------- 1 | #include "Queue.h" 2 | 3 | Queue* Queue::Upload(int socketid, string path, int QueueID, ChanheProgress chanheprogress) 4 | { 5 | try 6 | { 7 | Queue* item = new Queue(); 8 | item->QueueID = QueueID; 9 | item->chanheprogress = chanheprogress; 10 | item->SocketID = socketid; 11 | item->FileName = FileHandler::GetFileNameWhitOutExtention(path); 12 | item->FileExtention = FileHandler::GetFileExtention(path); 13 | item->FilePath = path; 14 | item->Index = 0; 15 | item->Treansfered = 0; 16 | item->Progress = 0; 17 | item->LastProgress = 0; 18 | item->Type = QueueTYPE::upload; 19 | item->readfile = std::ifstream(path, std::ios::binary); 20 | if (!item->readfile.is_open()) 21 | return nullptr; 22 | item->Length = item->readfile.seekg(0, std::ios::end).tellg(); 23 | item->readfile.seekg(0); 24 | return item; 25 | } 26 | catch (...) 27 | { 28 | return nullptr; 29 | } 30 | } 31 | Queue* Queue::Download(int socketid, int QueueID, string FileName, string FileExtention, long size, ChanheProgress chanheprogress) 32 | { 33 | try 34 | { 35 | Queue* item = new Queue(); 36 | item->QueueID = QueueID; 37 | item->chanheprogress = chanheprogress; 38 | item->SocketID = socketid; 39 | item->FileName = FileName; 40 | item->FileExtention = FileExtention; 41 | item->FilePath = FileHandler::Combine(".", FileHandler::TempPath(FileName)); 42 | item->Index = 0; 43 | item->Treansfered = 0; 44 | item->Progress = 0; 45 | item->LastProgress = 0; 46 | item->Type = QueueTYPE::download; 47 | item->writefile = std::ofstream(item->FilePath, std::ios::binary); 48 | if (!item->writefile.is_open()) 49 | return nullptr; 50 | item->Length = size; 51 | return item; 52 | 53 | } 54 | catch (...) 55 | { 56 | return nullptr; 57 | } 58 | } 59 | void Queue::SetProgress(int read) 60 | { 61 | this->Index += read; 62 | this->Treansfered += read; 63 | this->Progress = (int)((this->Treansfered * 100) / this->Length); 64 | if (this->LastProgress < this->Progress) 65 | this->LastProgress = this->Progress; 66 | if (this->LastProgress == 100) 67 | this->Close(); 68 | if (chanheprogress != NULL) 69 | chanheprogress(this->QueueID , this->LastProgress); 70 | 71 | } 72 | void Queue::Start() 73 | { 74 | this->Running = true; 75 | this->SendThread = thread([&]() {TrenasferProc(this); }); 76 | } 77 | void Queue::Close() 78 | { 79 | if (this->Type == QueueTYPE::download) 80 | { 81 | this->writefile.close(); 82 | FileHandler::ConvertTmpToStableFile(this->FilePath, this->FileExtention); 83 | } 84 | else if (this->Type == QueueTYPE::upload) 85 | { 86 | this->readfile.close(); 87 | this->Running = false; 88 | this->SendThread.detach(); 89 | } 90 | } 91 | void Queue::Write(const char const* Buffer, int Read) 92 | { 93 | this->writefile.write(Buffer, Read); 94 | SetProgress(Read); 95 | } 96 | void Queue::TrenasferProc(Queue* item) 97 | { 98 | while (item->Running && item->Index < item->Length) 99 | { 100 | sendDoor.lock(); 101 | 102 | long read = (item->Length - item->Index < SIZE_FileBuffer) ? item->Length - item->Index : SIZE_FileBuffer; 103 | 104 | FilePacket fp; 105 | fp.header = Header::chunck; 106 | fp.QueueId = item->QueueID; 107 | fp.Read = read; 108 | item->readfile.read(fp.Buffer, read); 109 | 110 | char Buffer[SIZE_Buffer]; 111 | memset(Buffer, 0, SIZE_Buffer); 112 | int size = Serialize< FilePacket>::serialize(Buffer, fp); 113 | send(this->SocketID, Buffer, size, 0); 114 | SetProgress(read); 115 | sendDoor.unlock(); 116 | std::this_thread::sleep_for(std::chrono::microseconds(5)); 117 | } 118 | } 119 | Queue::Queue() 120 | { 121 | 122 | } -------------------------------------------------------------------------------- /TCP/StepByStep/E04-Final/Cleint/Queue.h: -------------------------------------------------------------------------------- 1 | #ifndef QUEUE_H 2 | #define QUEUE_H 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "FileHandler.h" 9 | #include "Packets.h" 10 | #include "Serialize.h" 11 | #include "CleintConnection.h" 12 | using namespace std; 13 | class Queue; 14 | 15 | typedef void(__stdcall* ChanheProgress)(int Queueid, int value); 16 | enum QueueTYPE 17 | { 18 | download, 19 | upload 20 | }; 21 | class Queue 22 | { 23 | private: 24 | 25 | Queue(); 26 | void TrenasferProc(Queue*); 27 | string FilePath; 28 | thread SendThread; 29 | mutex sendDoor; 30 | ifstream readfile; 31 | ofstream writefile; 32 | long long Treansfered; 33 | long long Index; 34 | int Progress, LastProgress; 35 | bool Running; 36 | int SocketID; 37 | ChanheProgress chanheprogress; 38 | public: 39 | string FileName; 40 | string FileExtention; 41 | long long Length; 42 | int QueueID; 43 | QueueTYPE Type; 44 | static Queue* Upload(int socketid, string path, int QueueID, ChanheProgress chanheprogress); 45 | static Queue* Download(int socketid, int QueueID, string FileName, string FileExtention, long size, ChanheProgress chanheprogress); 46 | void SetProgress(int read); 47 | void Start(); 48 | void Close(); 49 | void Write(const char const* Buffer, int Read); 50 | 51 | }; 52 | #endif // !QUEUE_H 53 | -------------------------------------------------------------------------------- /TCP/StepByStep/E04-Final/Cleint/Serialize.h: -------------------------------------------------------------------------------- 1 | #ifndef SERIALIZE_H 2 | #define SERIALIZE_H 3 | #include 4 | template 5 | class Serialize 6 | { 7 | public: 8 | static size_t size(const Type input) 9 | { 10 | return sizeof(input); 11 | } 12 | static size_t serialize(char* const Buffer , Type input) 13 | { 14 | memcpy(Buffer, &input, sizeof(input)); 15 | return sizeof(input); 16 | } 17 | static size_t deserialize(char* Buffer, Type& output) 18 | { 19 | memcpy(&output, Buffer, sizeof(output)); 20 | return sizeof(output); 21 | } 22 | }; 23 | #endif // !SERIALIZE_H 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /TCP/StepByStep/E04-Final/Cleint/Source.cpp: -------------------------------------------------------------------------------- 1 | #include "CleintConnection.h" 2 | #include 3 | #include 4 | #include "Serialize.h" 5 | #include 6 | #include "Queue.h" 7 | CleintConnection tcpConnection; 8 | std::mutex ClientLiatDoor; 9 | std::mutex QueueListDoor; 10 | std::map QueueList; 11 | 12 | void Client(bool flag) 13 | { 14 | 15 | } 16 | void __stdcall changeprogress(int queueid, int i) 17 | { 18 | QueueListDoor.lock(); 19 | if (i == 100) 20 | { 21 | QueueList.erase(queueid); 22 | } 23 | QueueListDoor.unlock(); 24 | clog << i << " % " << endl; 25 | } 26 | void StartDownload(int socketid, int queueid) 27 | { 28 | StartPacket sp; 29 | sp.header = Header::start; 30 | sp.QueueID = queueid; 31 | char Buffer[sizeof(StartPacket)]; 32 | memset(Buffer, 0, sizeof(StartPacket)); 33 | Serialize::serialize(Buffer, sp); 34 | send(socketid, Buffer, sizeof(StartPacket), 0); 35 | } 36 | 37 | void Reciev(char* buffer, int size) 38 | { 39 | Packet pk; 40 | Serialize::deserialize(buffer, pk); 41 | switch (pk.header) 42 | { 43 | case Header::message: 44 | { 45 | MessagePacket msp; 46 | Serialize::deserialize(buffer, msp); 47 | string username; 48 | 49 | cout << "\nServer : " << string(msp.Buffer, msp.size) << endl; 50 | } 51 | break; 52 | case Header::queue: 53 | { 54 | QueuePacket qp; 55 | Serialize::deserialize(buffer, qp); 56 | Queue* item = Queue::Download(tcpConnection.MySocket, qp.QueueID, qp.FileName, qp.FileExtention, qp.Size, changeprogress); 57 | QueueListDoor.lock(); 58 | QueueList.insert(std::pair(qp.QueueID, item)); 59 | QueueListDoor.unlock(); 60 | StartDownload(tcpConnection.MySocket, qp.QueueID); 61 | } 62 | break; 63 | case Header::start: 64 | { 65 | StartPacket sp; 66 | Serialize::deserialize(buffer, sp); 67 | QueueListDoor.lock(); 68 | auto item = QueueList.find(sp.QueueID); 69 | if (item != QueueList.end()) 70 | { 71 | item->second->Start(); 72 | } 73 | QueueListDoor.unlock(); 74 | } 75 | break; 76 | case Header::chunck: 77 | { 78 | FilePacket fp; 79 | Serialize::deserialize(buffer, fp); 80 | QueueListDoor.lock(); 81 | auto item = QueueList.find(fp.QueueId); 82 | Queue* queue = nullptr; 83 | if (item != QueueList.end()) 84 | queue = item->second; 85 | QueueListDoor.unlock(); 86 | queue->Write(fp.Buffer, fp.Read); 87 | } 88 | break; 89 | default: 90 | break; 91 | } 92 | } 93 | 94 | void sendmessage() 95 | { 96 | while (!tcpConnection.IsRunning); 97 | cout << "Enter your Message : "; 98 | string message; 99 | getline(cin, message); 100 | 101 | // Packting 102 | MessagePacket msp; 103 | msp.header = Header::message; 104 | msp.size = message.length(); 105 | memcpy(msp.Buffer, message.c_str(), msp.size); 106 | 107 | string username; 108 | 109 | char BUFFER[SIZE_Message]; 110 | memset(BUFFER, 0, SIZE_Message); 111 | Serialize::serialize(BUFFER, msp); 112 | 113 | send(tcpConnection.MySocket, BUFFER, SIZE_Message, 0); 114 | } 115 | void SendFile(string path) 116 | { 117 | 118 | QueueListDoor.lock(); 119 | int id; 120 | do 121 | { 122 | id = rand() % 9000 + 1000; 123 | } 124 | while (QueueList.find(id) != QueueList.end()); 125 | Queue* item = Queue::Upload(tcpConnection.MySocket, path, id, changeprogress); 126 | QueueList.insert(std::pair(id, item)); 127 | QueueListDoor.unlock(); 128 | 129 | QueuePacket qp; 130 | qp.header = Header::queue; 131 | memcpy(qp.FileExtention, item->FileExtention.c_str(), item->FileExtention.size()); 132 | memcpy(qp.FileName, item->FileName.c_str(), item->FileName.size()); 133 | qp.QueueID = id; 134 | qp.Size = item->Length; 135 | const int size = sizeof(QueuePacket); 136 | char Buffer[size]; 137 | memset(Buffer, 0, size); 138 | Serialize< QueuePacket>::serialize(Buffer, qp); 139 | send(tcpConnection.MySocket, Buffer, size, 0); 140 | } 141 | int main() 142 | { 143 | tcpConnection = CleintConnection("127.0.0.1", 7071, Client, Reciev); 144 | if (tcpConnection.Init()) 145 | { 146 | thread ConnectionThread = thread([&]() {tcpConnection.Start(); }); 147 | thread SendThread = thread([&]() { 148 | int m; 149 | std::cin >> m; 150 | SendFile("C:\\Users\\amirr\\Desktop\\AP_99\\Document\\CPPCLI_CSharpCLR.zip"); 151 | }); 152 | ConnectionThread.join(); 153 | SendThread.join(); 154 | } 155 | else 156 | { 157 | return 0; 158 | } 159 | } -------------------------------------------------------------------------------- /TCP/StepByStep/E04-Final/ServerDLL/FileHandler.h: -------------------------------------------------------------------------------- 1 | #ifndef FILEHANDLER_H 2 | #define FILEHANDLER_H 3 | #include 4 | #include 5 | using std::string; 6 | using std::ifstream; 7 | class FileHandler 8 | { 9 | public: 10 | static string GetFileName(string path) 11 | { 12 | for (int i = path.length(); i >= 0; i--) 13 | if (path[i] == '\\') 14 | return path.substr(i + 1); 15 | return path; 16 | } 17 | static string GetFileExtention(string path) 18 | { 19 | string filename = GetFileName(path); 20 | size_t i = filename.rfind('.', filename.length()); 21 | if (i != string::npos) { 22 | return(filename.substr(i, filename.length() - i)); 23 | } 24 | } 25 | static string GetFileNameWhitOutExtention(string path) 26 | { 27 | string filename = GetFileName(path); 28 | size_t i = filename.rfind('.', filename.length()); 29 | if (i != string::npos) { 30 | return(filename.substr(0, i)); 31 | } 32 | } 33 | static inline string Combine(string str1, string str2) 34 | { 35 | return str1 + "\\" + str2; 36 | } 37 | static inline string TempPath(string Filename, string Extention = ".tmp") 38 | { 39 | while (IsFileExist(Filename + Extention)) 40 | Filename += "_copy"; 41 | return Filename + Extention; 42 | 43 | } 44 | static inline bool IsFileExist(const string& name) { 45 | ifstream f(name.c_str()); 46 | return f.good(); 47 | } 48 | static bool ConvertTmpToStableFile(const string& tmppath, const string& destinationpath) 49 | { 50 | string fname; 51 | if (GetFileNameWhitOutExtention(destinationpath) != "") 52 | fname = GetFileNameWhitOutExtention(destinationpath) + GetFileExtention(destinationpath); 53 | else 54 | fname = GetFileNameWhitOutExtention(tmppath) + GetFileExtention(destinationpath); 55 | 56 | if (!IsFileExist(tmppath)) 57 | return 0; 58 | 59 | if (rename(tmppath.c_str(), fname.c_str()) != 0) 60 | ConvertTmpToStableFile(tmppath, GetFileNameWhitOutExtention(fname) + "_Copy" + GetFileExtention(destinationpath)); 61 | else 62 | return 1; 63 | } 64 | }; 65 | #endif -------------------------------------------------------------------------------- /TCP/StepByStep/E04-Final/ServerDLL/Packets.h: -------------------------------------------------------------------------------- 1 | #ifndef PACKET_H 2 | #define PACKET_H 3 | #define SIZE_Buffer (20*1024) 4 | #define SIZE_FileBuffer (SIZE_Buffer-12)-1 5 | #define SIZE_Message 1024 6 | #define SIZE_MessageBuffer SIZE_Message-8-1 7 | 8 | enum Header : char 9 | { 10 | queue, 11 | start, 12 | chunck, 13 | message 14 | }; 15 | struct Packet 16 | { 17 | Header header; 18 | }; 19 | struct StartPacket : public Packet 20 | { 21 | int QueueID; 22 | }; 23 | struct QueuePacket : public Packet 24 | { 25 | char FileName[165]; 26 | char FileExtention[205]; 27 | long Size; 28 | int QueueID; 29 | QueuePacket() 30 | { 31 | memset(FileName, 0, 165); 32 | memset(FileExtention, 0, 205); 33 | } 34 | }; 35 | struct FilePacket : public Packet 36 | { 37 | int QueueId; 38 | int Read; 39 | char Buffer[SIZE_FileBuffer]; 40 | FilePacket() 41 | { 42 | memset(Buffer, 0, SIZE_FileBuffer); 43 | } 44 | 45 | }; 46 | struct MessagePacket : public Packet 47 | { 48 | int size; 49 | char Buffer[SIZE_MessageBuffer]; 50 | MessagePacket() 51 | { 52 | memset(Buffer, 0, SIZE_MessageBuffer); 53 | } 54 | }; 55 | #endif // !PACKET_H -------------------------------------------------------------------------------- /TCP/StepByStep/E04-Final/ServerDLL/Queue.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "Queue.h" 3 | 4 | Queue* Queue::Upload(int socketid, string path, int QueueID , ChanheProgress chanheprogress) 5 | { 6 | try 7 | { 8 | Queue* item = new Queue(); 9 | item->QueueID = QueueID; 10 | item->chanheprogress = chanheprogress; 11 | item->SocketID = socketid; 12 | item->FileName = FileHandler::GetFileNameWhitOutExtention(path); 13 | item->FileExtention = FileHandler::GetFileExtention(path); 14 | item->FilePath = path; 15 | item->Index = 0; 16 | item->Treansfered = 0; 17 | item->Progress = 0; 18 | item->LastProgress = 0; 19 | item->Type = QueueTYPE::upload; 20 | item->readfile = std::ifstream(path, std::ios::binary); 21 | if (!item->readfile.is_open()) 22 | return nullptr; 23 | item->Length = item->readfile.seekg(0, std::ios::end).tellg(); 24 | item->readfile.seekg(0); 25 | return item; 26 | 27 | } 28 | catch (...) 29 | { 30 | return nullptr; 31 | } 32 | } 33 | Queue* Queue::Download(int socketid,int QueueID, string FileName, string FileExtention, long size, ChanheProgress chanheprogress) 34 | { 35 | try 36 | { 37 | Queue* item = new Queue(); 38 | item->QueueID = QueueID; 39 | item->chanheprogress = chanheprogress; 40 | item->SocketID = socketid; 41 | item->FileName = FileName; 42 | item->FileExtention = FileExtention; 43 | item->FilePath = FileHandler::Combine(".", FileHandler::TempPath(FileName)); 44 | item->Index = 0; 45 | item->Treansfered = 0; 46 | item->Progress = 0; 47 | item->LastProgress = 0; 48 | item->Type = QueueTYPE::download; 49 | item->writefile = std::ofstream(item->FilePath, std::ios::binary); 50 | if (!item->writefile.is_open()) 51 | return nullptr; 52 | item->Length = size; 53 | return item; 54 | } 55 | catch (...) 56 | { 57 | return nullptr; 58 | } 59 | } 60 | void Queue::SetProgress(int read) 61 | { 62 | this->Index += read; 63 | this->Treansfered += read; 64 | this->Progress = (int)((this->Treansfered * 100) / this->Length); 65 | if (this->LastProgress < this->Progress) 66 | this->LastProgress = this->Progress; 67 | if (this->LastProgress == 100) 68 | this->Close(); 69 | if (chanheprogress != NULL) 70 | chanheprogress(this->QueueID, this->LastProgress); 71 | } 72 | void Queue::Start() 73 | { 74 | this->Running = true; 75 | this->SendThread = thread([&]() {TrenasferProc(this); }); 76 | } 77 | void Queue::Close() 78 | { 79 | if (this->Type == QueueTYPE::download) 80 | { 81 | this->writefile.close(); 82 | FileHandler::ConvertTmpToStableFile(this->FilePath , this->FileExtention); 83 | } 84 | else if (this->Type == QueueTYPE::upload) 85 | { 86 | this->readfile.close(); 87 | this->Running = false; 88 | this->SendThread.detach(); 89 | } 90 | } 91 | void Queue::Write(const char const* Buffer, int Read) 92 | { 93 | 94 | if (this->writefile.is_open()) 95 | { 96 | this->writefile.write(Buffer, Read); 97 | SetProgress(Read); 98 | } 99 | } 100 | void Queue::TrenasferProc(Queue* item) 101 | { 102 | while (item->Running && item->Index < item->Length) 103 | { 104 | sendDoor.lock(); 105 | 106 | long read = (item->Length - item->Index < SIZE_FileBuffer) ? item->Length - item->Index : SIZE_FileBuffer; 107 | 108 | FilePacket fp; 109 | fp.header = Header::chunck; 110 | fp.QueueId = item->QueueID; 111 | fp.Read = read; 112 | item->readfile.read(fp.Buffer, read); 113 | 114 | char Buffer[SIZE_Buffer]; 115 | memset(Buffer, 0, SIZE_Buffer); 116 | int size = Serialize< FilePacket>::serialize(Buffer, fp); 117 | send(this->SocketID, Buffer, size, 0); 118 | SetProgress(read); 119 | sendDoor.unlock(); 120 | std::this_thread::sleep_for(std::chrono::microseconds(5)); 121 | } 122 | 123 | } 124 | Queue::Queue() 125 | { 126 | 127 | } -------------------------------------------------------------------------------- /TCP/StepByStep/E04-Final/ServerDLL/Queue.h: -------------------------------------------------------------------------------- 1 | #ifndef QUEUE_H 2 | #define QUEUE_H 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "FileHandler.h" 9 | #include "Packets.h" 10 | #include "Serialize.h" 11 | #include "TCPListener.h" 12 | using namespace std; 13 | 14 | typedef void (*ChanheProgress)(int Queueid , int value); 15 | enum QueueTYPE 16 | { 17 | download, 18 | upload 19 | }; 20 | 21 | class Queue 22 | { 23 | private: 24 | 25 | Queue(); 26 | void TrenasferProc(Queue*); 27 | string FilePath; 28 | thread SendThread; 29 | mutex sendDoor; 30 | ifstream readfile; 31 | ofstream writefile; 32 | long long Treansfered; 33 | long long Index; 34 | int Progress, LastProgress; 35 | bool Running; 36 | 37 | ChanheProgress chanheprogress; 38 | public: 39 | int SocketID; 40 | string FileName; 41 | string FileExtention; 42 | long long Length; 43 | int QueueID; 44 | QueueTYPE Type; 45 | static Queue* Upload(int socketid , string path , int QueueID , ChanheProgress chanheprogress); 46 | static Queue* Download(int socketid , int QueueID, string FileName , string FileExtention , long size, ChanheProgress chanheprogress); 47 | void SetProgress(int read); 48 | void Start(); 49 | void Close(); 50 | void Write(const char const* Buffer , int Read); 51 | 52 | }; 53 | #endif // !QUEUE_H 54 | -------------------------------------------------------------------------------- /TCP/StepByStep/E04-Final/ServerDLL/Serialize.h: -------------------------------------------------------------------------------- 1 | #ifndef SERIALIZE_H 2 | #define SERIALIZE_H 3 | #include 4 | template 5 | class Serialize 6 | { 7 | public: 8 | static size_t size(const Type input) 9 | { 10 | return sizeof(input); 11 | } 12 | static size_t serialize(char* const Buffer , Type input) 13 | { 14 | memcpy(Buffer, &input, sizeof(input)); 15 | return sizeof(input); 16 | } 17 | static size_t deserialize(char* Buffer, Type& output) 18 | { 19 | memcpy(&output, Buffer, sizeof(output)); 20 | return sizeof(output); 21 | } 22 | }; 23 | #endif // !SERIALIZE_H 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /TCP/StepByStep/E04-Final/ServerDLL/ServerDLL.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 16.0 23 | Win32Proj 24 | {5281063a-f0d8-4f30-b291-dd2a8d9e4425} 25 | ServerDLL 26 | 10.0 27 | 28 | 29 | 30 | DynamicLibrary 31 | true 32 | v142 33 | Unicode 34 | 35 | 36 | DynamicLibrary 37 | false 38 | v142 39 | true 40 | Unicode 41 | 42 | 43 | DynamicLibrary 44 | true 45 | v142 46 | Unicode 47 | 48 | 49 | DynamicLibrary 50 | false 51 | v142 52 | true 53 | Unicode 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | true 75 | 76 | 77 | false 78 | 79 | 80 | true 81 | 82 | 83 | false 84 | 85 | 86 | 87 | Level3 88 | true 89 | WIN32;_DEBUG;SERVERDLL_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 90 | true 91 | Use 92 | pch.h 93 | 94 | 95 | Windows 96 | true 97 | false 98 | 99 | 100 | 101 | 102 | Level3 103 | true 104 | true 105 | true 106 | WIN32;NDEBUG;SERVERDLL_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 107 | true 108 | Use 109 | pch.h 110 | 111 | 112 | Windows 113 | true 114 | true 115 | true 116 | false 117 | 118 | 119 | 120 | 121 | Level3 122 | true 123 | _DEBUG;SERVERDLL_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 124 | true 125 | Use 126 | pch.h 127 | 128 | 129 | Windows 130 | true 131 | false 132 | 133 | 134 | 135 | 136 | Level3 137 | true 138 | true 139 | true 140 | NDEBUG;SERVERDLL_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 141 | true 142 | Use 143 | pch.h 144 | 145 | 146 | Windows 147 | true 148 | true 149 | true 150 | false 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | Create 167 | Create 168 | Create 169 | Create 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | -------------------------------------------------------------------------------- /TCP/StepByStep/E04-Final/ServerDLL/ServerDLL.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Header Files 20 | 21 | 22 | Header Files 23 | 24 | 25 | Header Files 26 | 27 | 28 | Header Files 29 | 30 | 31 | Header Files 32 | 33 | 34 | Header Files 35 | 36 | 37 | Header Files 38 | 39 | 40 | Header Files 41 | 42 | 43 | 44 | 45 | Source Files 46 | 47 | 48 | Source Files 49 | 50 | 51 | Source Files 52 | 53 | 54 | Source Files 55 | 56 | 57 | Source Files 58 | 59 | 60 | -------------------------------------------------------------------------------- /TCP/StepByStep/E04-Final/ServerDLL/ServerDLL.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /TCP/StepByStep/E04-Final/ServerDLL/Source.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "Source.h" 3 | 4 | 5 | void Client(int Socketid , bool flag) 6 | { 7 | if (flag) 8 | { 9 | string username = "Amirreza" + to_string(ClientNum++); 10 | ClientLiatDoor.lock(); 11 | ClientList.insert(pair(username, Socketid)); 12 | ClientLiatDoor.unlock(); 13 | uiNewClient(username, 1); 14 | return; 15 | } 16 | else 17 | { 18 | string username; 19 | ClientLiatDoor.lock(); 20 | for (auto target : ClientList) 21 | { 22 | if (target.second == Socketid) 23 | { 24 | username = target.first; 25 | break; 26 | } 27 | } 28 | ClientList.erase(username); 29 | ClientLiatDoor.unlock(); 30 | uiNewClient(username, 0); 31 | return; 32 | } 33 | } 34 | void changeprogress(int queueid , int i ) 35 | { 36 | QueueListDoor.lock(); 37 | if (i == 100) 38 | { 39 | Queue_List.erase(queueid); 40 | } 41 | QueueListDoor.unlock(); 42 | uiChangeProgress(queueid, i); 43 | } 44 | void StartDownload( int queueid) 45 | { 46 | StartPacket sp; 47 | sp.header = Header::start; 48 | sp.QueueID = queueid; 49 | char Buffer[sizeof(StartPacket)]; 50 | memset(Buffer, 0, sizeof(StartPacket)); 51 | Serialize::serialize(Buffer, sp); 52 | QueueListDoor.lock(); 53 | send(Queue_List.find(queueid)->second->SocketID, Buffer , sizeof(StartPacket) , 0); 54 | QueueListDoor.unlock(); 55 | } 56 | void Recieve(int socketid , char* buffer , int size) 57 | { 58 | Packet pk; 59 | Serialize::deserialize(buffer, pk); 60 | switch (pk.header) 61 | { 62 | case Header::message: 63 | { 64 | MessagePacket msp; 65 | Serialize::deserialize(buffer, msp); 66 | string username; 67 | for (auto target : ClientList) 68 | { 69 | if (target.second == socketid) 70 | { 71 | username = target.first; 72 | break; 73 | } 74 | } 75 | 76 | } 77 | break; 78 | case Header::queue: 79 | { 80 | QueuePacket qp; 81 | Serialize::deserialize(buffer, qp); 82 | Queue* item = Queue::Download(socketid, qp.QueueID, qp.FileName, qp.FileExtention, qp.Size, changeprogress); 83 | QueueListDoor.lock(); 84 | Queue_List.insert(std::pair(qp.QueueID, item)); 85 | QueueListDoor.unlock(); 86 | uiNewRecieve(qp.QueueID, qp.FileName, qp.FileExtention); 87 | } 88 | break; 89 | case Header::start: 90 | { 91 | StartPacket sp; 92 | Serialize::deserialize(buffer, sp); 93 | QueueListDoor.lock(); 94 | auto item = Queue_List.find(sp.QueueID); 95 | if (item != Queue_List.end()) 96 | { 97 | item->second->Start(); 98 | } 99 | QueueListDoor.unlock(); 100 | } 101 | break; 102 | case Header::chunck: 103 | { 104 | FilePacket fp; 105 | Serialize::deserialize(buffer, fp); 106 | QueueListDoor.lock(); 107 | auto item = Queue_List.find(fp.QueueId); 108 | Queue* queue = nullptr; 109 | if (item != Queue_List.end()) 110 | queue = item->second; 111 | QueueListDoor.unlock(); 112 | queue->Write(fp.Buffer, fp.Read); 113 | } 114 | break; 115 | default: 116 | break; 117 | } 118 | } 119 | 120 | void sendmessage() 121 | { 122 | while (!tcpServer.IsRunning); 123 | 124 | cout << "\nEnter your Message : "; 125 | string message; 126 | getline(cin, message); 127 | 128 | // Packting 129 | MessagePacket msp; 130 | msp.header = Header::message; 131 | msp.size = message.length(); 132 | memcpy(msp.Buffer, message.c_str(), msp.size); 133 | 134 | string username; 135 | ClientLiatDoor.lock(); 136 | do 137 | { 138 | cout << "Enter UserName : "; 139 | getline(cin, username); 140 | } while (ClientList.find(username) == ClientList.end()); 141 | int ClinetID = ClientList.find(username)->second; 142 | ClientLiatDoor.unlock(); 143 | 144 | char BUFFER[SIZE_Message]; 145 | memset(BUFFER, 0, SIZE_Message); 146 | Serialize::serialize(BUFFER, msp); 147 | 148 | send(ClinetID, BUFFER, SIZE_Message, 0); 149 | } 150 | int SendFile(string path , string username) 151 | { 152 | ClientLiatDoor.lock(); 153 | int ClinetID = ClientList.find(username)->second; 154 | ClientLiatDoor.unlock(); 155 | QueueListDoor.lock(); 156 | int id; 157 | do 158 | { 159 | id = rand() % 9000 + 1000; 160 | } while (Queue_List.find(id) != Queue_List.end()); 161 | Queue* item = Queue::Upload(ClinetID, path, id, changeprogress); 162 | Queue_List.insert(std::pair(id, item)); 163 | QueueListDoor.unlock(); 164 | 165 | QueuePacket qp; 166 | qp.header = Header::queue; 167 | memcpy(qp.FileExtention, item->FileExtention.c_str(), item->FileExtention.size()); 168 | memcpy(qp.FileName, item->FileName.c_str(), item->FileName.size()); 169 | qp.QueueID = id; 170 | qp.Size = item->Length; 171 | const int size = sizeof(QueuePacket); 172 | char Buffer[size]; 173 | memset(Buffer , 0 , size); 174 | Serialize< QueuePacket>::serialize(Buffer, qp); 175 | send(ClinetID , Buffer , size ,0); 176 | return item->QueueID; 177 | } 178 | 179 | void Startup(string ip, int port, UIChangeProgress uiChangeprogress, UINewClient uiNewclient, UINewRecieve uiNewrecieve) 180 | { 181 | 182 | tcpServer = TCPListener(ip, port, Client, Recieve); 183 | if (tcpServer.Init()) 184 | { 185 | thread ConnectionThread = thread([&]() {tcpServer.Start();}); 186 | 187 | 188 | uiChangeProgress = uiChangeprogress; 189 | uiNewClient = uiNewclient; 190 | uiNewRecieve = uiNewrecieve; 191 | 192 | ConnectionThread.join(); 193 | 194 | } 195 | else 196 | { 197 | return; 198 | } 199 | } -------------------------------------------------------------------------------- /TCP/StepByStep/E04-Final/ServerDLL/Source.h: -------------------------------------------------------------------------------- 1 | #ifndef SOURCE_H 2 | #define SOURCE_H 3 | #include 4 | 5 | #include "TCPListener.h" 6 | #include "Serialize.h" 7 | #include 8 | #include 9 | #include 10 | #include "Queue.h" 11 | 12 | map ClientList; 13 | static int ClientNum = 0; 14 | TCPListener tcpServer; 15 | std::mutex ClientLiatDoor; 16 | std::mutex QueueListDoor; 17 | std::map Queue_List; 18 | 19 | typedef void(* UIChangeProgress)(int queueid, int value); 20 | typedef void(* UINewClient)(string username , bool flag); 21 | typedef void(* UINewRecieve)(int Queueid, std::string Name, std::string Extention); 22 | 23 | UIChangeProgress uiChangeProgress; 24 | UINewClient uiNewClient; 25 | UINewRecieve uiNewRecieve; 26 | 27 | 28 | #ifdef UI_ALPI 29 | #define UI_ALPI __declspec(dllexport) 30 | #else 31 | #define UI_ALPI __declspec(dllimport) 32 | #endif // DEBUG 33 | 34 | 35 | void Client(int Socketid, bool flag); 36 | void changeprogress(int queueid, int i); 37 | void Recieve(int socketid, char* buffer, int size); 38 | 39 | 40 | extern "C" UI_ALPI void Startup(string ip, int port, UIChangeProgress uiChangeprogress, UINewClient uiNewclient, UINewRecieve uiNewrecieve); 41 | 42 | extern "C" UI_ALPI void StartDownload( int queueid); 43 | extern "C" UI_ALPI void sendmessage(); 44 | extern "C" UI_ALPI int SendFile(string path, string username); 45 | #endif // !SOURCE_H 46 | -------------------------------------------------------------------------------- /TCP/StepByStep/E04-Final/ServerDLL/TCPListener.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "TCPListener.h" 3 | 4 | TCPListener::TCPListener() 5 | { 6 | 7 | } 8 | __stdcall TCPListener::TCPListener(string ip, int port, Client_Handler clientHandler, Recive_Handler reciveHandler) 9 | : ip(ip) , port(port) , clientHandler(clientHandler) , reciveHandler(reciveHandler) 10 | { 11 | 12 | } 13 | bool TCPListener::Init() 14 | { 15 | WSADATA WindowsSocketInof; 16 | WORD Version = MAKEWORD(2, 2); 17 | int res = WSAStartup(Version , &WindowsSocketInof); 18 | return res == 0; 19 | } 20 | void TCPListener::Start() 21 | { 22 | Server = CreateSocket(); 23 | if (Server != INVALID_SOCKET) 24 | { 25 | IsRunning = true; 26 | FD_ZERO(&master); 27 | FD_ZERO(&Read); 28 | FD_SET(Server, &master); 29 | Read = master; 30 | while (true) 31 | Run(); 32 | } 33 | else 34 | { 35 | throw exception("Start Function : Server Connection Failed!"); 36 | } 37 | } 38 | void TCPListener::CleanUp() 39 | { 40 | IsRunning = false; 41 | closesocket(Server); 42 | WSACleanup(); 43 | } 44 | TCPListener::~TCPListener() 45 | { 46 | CleanUp(); 47 | } 48 | void TCPListener::Run() 49 | { 50 | Read = master; 51 | int SocketCount = select(0, &Read, nullptr, nullptr, nullptr); 52 | if (SocketCount <= 0) 53 | { 54 | CleanUp(); 55 | throw exception("Run Function : Server Connection Failed!"); 56 | } 57 | else 58 | { 59 | for (int i = 0; i < SocketCount; i++) 60 | { 61 | SOCKET SelectedSocket = Read.fd_array[i]; 62 | if (SelectedSocket == Server) 63 | { 64 | SOCKET NewClient = accept(Server, nullptr, nullptr); 65 | FD_SET(NewClient, &master); 66 | clientHandler(NewClient, true); 67 | } 68 | else 69 | { 70 | char BUFFER[SIZE_Buffer]; 71 | memset(BUFFER, 0, SIZE_Buffer); 72 | int ByteRecv = recv(SelectedSocket, BUFFER, SIZE_Buffer, 0); 73 | if (ByteRecv <= 0) 74 | { 75 | FD_CLR(SelectedSocket , &master); 76 | clientHandler(SelectedSocket, false); 77 | } 78 | else 79 | { 80 | if (ByteRecv >= 1) 81 | reciveHandler(SelectedSocket, BUFFER, ByteRecv); 82 | } 83 | } 84 | } 85 | } 86 | } 87 | SOCKET TCPListener::CreateSocket() 88 | { 89 | SOCKET Server = socket(AF_INET, SOCK_STREAM, 0); 90 | if (Server != INVALID_SOCKET) 91 | { 92 | sockaddr_in ServerAddress; 93 | ServerAddress.sin_family = AF_INET; // IP v4 94 | ServerAddress.sin_port = htons(port); 95 | ServerAddress.sin_addr.S_un.S_addr = INADDR_ANY; 96 | int res = ::bind(Server , (sockaddr*)&ServerAddress , sizeof(ServerAddress)); 97 | if (res != SOCKET_ERROR) 98 | { 99 | res = listen(Server, SOMAXCONN); 100 | if (res != SOCKET_ERROR) 101 | { 102 | return Server; 103 | } 104 | else 105 | { 106 | closesocket(Server); 107 | CleanUp(); 108 | return -1; 109 | } 110 | } 111 | else 112 | { 113 | closesocket(Server); 114 | CleanUp(); 115 | return -1; 116 | } 117 | } 118 | else 119 | { 120 | closesocket(Server); 121 | CleanUp(); 122 | return -1; 123 | } 124 | } -------------------------------------------------------------------------------- /TCP/StepByStep/E04-Final/ServerDLL/TCPListener.h: -------------------------------------------------------------------------------- 1 | #ifndef TCPListener_H 2 | #define TCPListener_H 3 | #include 4 | #include 5 | #include "Packets.h" 6 | #include 7 | 8 | 9 | #pragma comment (lib , "Ws2_32.lib") 10 | using namespace std; 11 | typedef void (* Client_Handler)(int SocketID, bool flag); 12 | typedef void (*Recive_Handler)(int SockerID, char* Buffer, int DataLegth); 13 | 14 | class TCPListener 15 | { 16 | public: 17 | bool IsRunning; 18 | TCPListener(); 19 | TCPListener(string ip, int port, Client_Handler , Recive_Handler ); 20 | bool Init(); 21 | void Start(); 22 | void CleanUp(); 23 | ~TCPListener(); 24 | private: 25 | fd_set master; 26 | fd_set Read; 27 | Client_Handler clientHandler; 28 | Recive_Handler reciveHandler; 29 | string ip; 30 | SOCKET Server; 31 | int port; 32 | void Run(); 33 | SOCKET CreateSocket(); 34 | }; 35 | #endif // !TCPListener_H 36 | -------------------------------------------------------------------------------- /TCP/StepByStep/E04-Final/ServerDLL/dllmain.cpp: -------------------------------------------------------------------------------- 1 | // dllmain.cpp : Defines the entry point for the DLL application. 2 | #include "pch.h" 3 | 4 | BOOL APIENTRY DllMain( HMODULE hModule, 5 | DWORD ul_reason_for_call, 6 | LPVOID lpReserved 7 | ) 8 | { 9 | switch (ul_reason_for_call) 10 | { 11 | case DLL_PROCESS_ATTACH: 12 | case DLL_THREAD_ATTACH: 13 | case DLL_THREAD_DETACH: 14 | case DLL_PROCESS_DETACH: 15 | break; 16 | } 17 | return TRUE; 18 | } 19 | 20 | -------------------------------------------------------------------------------- /TCP/StepByStep/E04-Final/ServerDLL/framework.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers 4 | // Windows Header Files 5 | #include 6 | -------------------------------------------------------------------------------- /TCP/StepByStep/E04-Final/ServerDLL/pch.cpp: -------------------------------------------------------------------------------- 1 | // pch.cpp: source file corresponding to the pre-compiled header 2 | 3 | #include "pch.h" 4 | 5 | // When you are using pre-compiled headers, this source file is necessary for compilation to succeed. 6 | -------------------------------------------------------------------------------- /TCP/StepByStep/E04-Final/ServerDLL/pch.h: -------------------------------------------------------------------------------- 1 | // pch.h: This is a precompiled header file. 2 | // Files listed below are compiled only once, improving build performance for future builds. 3 | // This also affects IntelliSense performance, including code completion and many code browsing features. 4 | // However, files listed here are ALL re-compiled if any one of them is updated between builds. 5 | // Do not add files here that you will be updating frequently as this negates the performance advantage. 6 | 7 | #ifndef PCH_H 8 | #define PCH_H 9 | 10 | // add headers that you want to pre-compile here 11 | #include "framework.h" 12 | 13 | #endif //PCH_H 14 | -------------------------------------------------------------------------------- /TCP/StepByStep/E04-Final/SocketUI/MyForm.cpp: -------------------------------------------------------------------------------- 1 | #include "MyForm.h" 2 | using namespace System; 3 | using namespace System::Windows::Forms; 4 | 5 | [STAThreadAttribute] 6 | void Main(array^ args) 7 | { 8 | Application::EnableVisualStyles(); 9 | Application::SetCompatibleTextRenderingDefault(false); 10 | SocketUI::MyForm form; 11 | Application::Run(% form); 12 | } 13 | -------------------------------------------------------------------------------- /TCP/StepByStep/E04-Final/SocketUI/MyForm.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | namespace SocketUI { 5 | 6 | using namespace System; 7 | using namespace System::ComponentModel; 8 | using namespace System::Collections; 9 | using namespace System::Windows::Forms; 10 | using namespace System::Data; 11 | using namespace System::Drawing; 12 | using namespace System::Threading; 13 | using namespace System::IO; 14 | using namespace System::Runtime::InteropServices; 15 | 16 | 17 | delegate void DelADDCLIENT(String^,bool); 18 | delegate void DelADDQUEUE(array< String^>^); 19 | delegate void DelProgressBar(int,int); 20 | delegate void DelCompelete(int); 21 | 22 | 23 | [UnmanagedFunctionPointerAttribute(CallingConvention::Cdecl)] 24 | delegate void UIChangeProgress(int queueid, int value); 25 | [UnmanagedFunctionPointerAttribute(CallingConvention::Cdecl)] 26 | delegate void UINewClient(std::string, bool flag); 27 | [UnmanagedFunctionPointerAttribute(CallingConvention::Cdecl)] 28 | delegate void UINewRecieve(int Queueid, std::string Name, std::string Extention); 29 | 30 | 31 | [DllImport("ServerDLL.dll" , CallingConvention = CallingConvention::Cdecl)] 32 | void Startup(std::string , int , UIChangeProgress^, UINewClient^, UINewRecieve^); 33 | 34 | [DllImport("ServerDLL.dll", CallingConvention = CallingConvention::Cdecl)] 35 | int SendFile(std::string path, std::string username); 36 | 37 | [DllImport("ServerDLL.dll", CallingConvention = CallingConvention::Cdecl)] 38 | void StartDownload(int queueid); 39 | 40 | public ref class MyForm : public System::Windows::Forms::Form 41 | { 42 | DelADDCLIENT^ Event_ADDCLIENT; 43 | DelADDQUEUE^ Event_ADDQUEUE; 44 | DelProgressBar^ Event_Progress; 45 | UIChangeProgress^ Event_UIChangeProgress; 46 | UINewClient^ Event_UINewClient; 47 | UINewRecieve^ Event_UINewRecieve; 48 | DelCompelete^ Event_Compelete; 49 | bool IsRunning; 50 | bool IsTransfer; 51 | public:MyForm() 52 | { 53 | InitializeComponent(); 54 | Rigster(); 55 | IsRunning = false; 56 | IsTransfer = false; 57 | } 58 | void Rigster() 59 | { 60 | Event_ADDCLIENT += gcnew DelADDCLIENT(this, &MyForm::AddClient); 61 | Event_ADDQUEUE += gcnew DelADDQUEUE(this, &MyForm::AddNewQueue); 62 | Event_Progress += gcnew DelProgressBar(this, &MyForm::ChangeProgress); 63 | Event_UIChangeProgress += gcnew UIChangeProgress(this, &MyForm::ChangeProgress); 64 | Event_UINewClient += gcnew UINewClient(this, &MyForm::ChangeClient); 65 | Event_UINewRecieve += gcnew UINewRecieve(this, &MyForm::NewQueueRow); 66 | Event_Compelete += gcnew DelCompelete(this, &MyForm::CompeleteTransfer); 67 | 68 | } 69 | protected: 70 | /// 71 | /// Clean up any resources being used. 72 | /// 73 | ~MyForm() 74 | { 75 | if (components) 76 | { 77 | delete components; 78 | } 79 | } 80 | 81 | protected: 82 | 83 | private: System::Windows::Forms::ColumnHeader^ RowIndex; 84 | private: System::Windows::Forms::ColumnHeader^ Name; 85 | private: System::Windows::Forms::ColumnHeader^ Tenasferd; 86 | private: System::Windows::Forms::ColumnHeader^ Type; 87 | private: System::Windows::Forms::ColumnHeader^ Time; 88 | private: System::Windows::Forms::ColumnHeader^ Date; 89 | private: System::Windows::Forms::ProgressBar^ PBTreansfered; 90 | private: System::Windows::Forms::ComboBox^ Clients; 91 | private: System::Windows::Forms::TextBox^ Port; 92 | private: System::Windows::Forms::Label^ label2; 93 | private: System::Windows::Forms::TextBox^ IP; 94 | private: System::Windows::Forms::Label^ label1; 95 | private: System::Windows::Forms::Button^ BTNStart; 96 | private: System::Windows::Forms::Button^ BTNDonwload; 97 | 98 | 99 | private: System::Windows::Forms::MenuStrip^ menuStrip1; 100 | private: System::Windows::Forms::ToolStripMenuItem^ fileToolStripMenuItem; 101 | private: System::Windows::Forms::ToolStripMenuItem^ ServerMode; 102 | private: System::Windows::Forms::ToolStripMenuItem^ ClientMode; 103 | private: System::Windows::Forms::ToolStripMenuItem^ dataModeToolStripMenuItem; 104 | private: System::Windows::Forms::ToolStripMenuItem^ fileToolStripMenuItem1; 105 | private: System::Windows::Forms::ToolStripMenuItem^ messageToolStripMenuItem; 106 | private: System::Windows::Forms::ListView^ QueueList; 107 | private: System::Windows::Forms::ColumnHeader^ ID; 108 | 109 | private: System::Windows::Forms::ColumnHeader^ FileName; 110 | private: System::Windows::Forms::ColumnHeader^ FileExtention; 111 | private: System::Windows::Forms::ColumnHeader^ Condition; 112 | 113 | private: System::Windows::Forms::ColumnHeader^ DateTime; 114 | private: System::Windows::Forms::ColumnHeader^ QueueType; 115 | private: System::Windows::Forms::ToolStripMenuItem^ uploadToolStripMenuItem; 116 | 117 | private: 118 | /// 119 | /// Required designer variable. 120 | /// 121 | System::ComponentModel::Container^ components; 122 | 123 | #pragma region Windows Form Designer generated code 124 | /// 125 | /// Required method for Designer support - do not modify 126 | /// the contents of this method with the code editor. 127 | /// 128 | void InitializeComponent(void) 129 | { 130 | this->RowIndex = (gcnew System::Windows::Forms::ColumnHeader()); 131 | this->Name = (gcnew System::Windows::Forms::ColumnHeader()); 132 | this->Tenasferd = (gcnew System::Windows::Forms::ColumnHeader()); 133 | this->Type = (gcnew System::Windows::Forms::ColumnHeader()); 134 | this->Time = (gcnew System::Windows::Forms::ColumnHeader()); 135 | this->Date = (gcnew System::Windows::Forms::ColumnHeader()); 136 | this->PBTreansfered = (gcnew System::Windows::Forms::ProgressBar()); 137 | this->Clients = (gcnew System::Windows::Forms::ComboBox()); 138 | this->Port = (gcnew System::Windows::Forms::TextBox()); 139 | this->label2 = (gcnew System::Windows::Forms::Label()); 140 | this->IP = (gcnew System::Windows::Forms::TextBox()); 141 | this->label1 = (gcnew System::Windows::Forms::Label()); 142 | this->BTNStart = (gcnew System::Windows::Forms::Button()); 143 | this->BTNDonwload = (gcnew System::Windows::Forms::Button()); 144 | this->menuStrip1 = (gcnew System::Windows::Forms::MenuStrip()); 145 | this->fileToolStripMenuItem = (gcnew System::Windows::Forms::ToolStripMenuItem()); 146 | this->ServerMode = (gcnew System::Windows::Forms::ToolStripMenuItem()); 147 | this->ClientMode = (gcnew System::Windows::Forms::ToolStripMenuItem()); 148 | this->dataModeToolStripMenuItem = (gcnew System::Windows::Forms::ToolStripMenuItem()); 149 | this->fileToolStripMenuItem1 = (gcnew System::Windows::Forms::ToolStripMenuItem()); 150 | this->uploadToolStripMenuItem = (gcnew System::Windows::Forms::ToolStripMenuItem()); 151 | this->messageToolStripMenuItem = (gcnew System::Windows::Forms::ToolStripMenuItem()); 152 | this->QueueList = (gcnew System::Windows::Forms::ListView()); 153 | this->ID = (gcnew System::Windows::Forms::ColumnHeader()); 154 | this->FileName = (gcnew System::Windows::Forms::ColumnHeader()); 155 | this->FileExtention = (gcnew System::Windows::Forms::ColumnHeader()); 156 | this->Condition = (gcnew System::Windows::Forms::ColumnHeader()); 157 | this->DateTime = (gcnew System::Windows::Forms::ColumnHeader()); 158 | this->QueueType = (gcnew System::Windows::Forms::ColumnHeader()); 159 | this->menuStrip1->SuspendLayout(); 160 | this->SuspendLayout(); 161 | // 162 | // RowIndex 163 | // 164 | this->RowIndex->Text = L"Index"; 165 | this->RowIndex->Width = 42; 166 | // 167 | // Name 168 | // 169 | this->Name->Text = L"File Name"; 170 | this->Name->Width = 118; 171 | // 172 | // Tenasferd 173 | // 174 | this->Tenasferd->Text = L"Tenasferd"; 175 | this->Tenasferd->Width = 66; 176 | // 177 | // Type 178 | // 179 | this->Type->Text = L"Type"; 180 | // 181 | // Time 182 | // 183 | this->Time->Text = L"Time"; 184 | this->Time->Width = 80; 185 | // 186 | // Date 187 | // 188 | this->Date->Text = L"Date"; 189 | this->Date->Width = 104; 190 | // 191 | // PBTreansfered 192 | // 193 | this->PBTreansfered->Location = System::Drawing::Point(12, 249); 194 | this->PBTreansfered->Name = L"PBTreansfered"; 195 | this->PBTreansfered->Size = System::Drawing::Size(419, 23); 196 | this->PBTreansfered->TabIndex = 17; 197 | // 198 | // Clients 199 | // 200 | this->Clients->FormattingEnabled = true; 201 | this->Clients->Location = System::Drawing::Point(296, 32); 202 | this->Clients->Name = L"Clients"; 203 | this->Clients->Size = System::Drawing::Size(121, 21); 204 | this->Clients->TabIndex = 16; 205 | this->Clients->Text = L"Client"; 206 | // 207 | // Port 208 | // 209 | this->Port->Location = System::Drawing::Point(175, 32); 210 | this->Port->Name = L"Port"; 211 | this->Port->Size = System::Drawing::Size(100, 20); 212 | this->Port->TabIndex = 15; 213 | this->Port->Text = L"7071"; 214 | // 215 | // label2 216 | // 217 | this->label2->AutoSize = true; 218 | this->label2->Location = System::Drawing::Point(143, 36); 219 | this->label2->Name = L"label2"; 220 | this->label2->Size = System::Drawing::Size(26, 13); 221 | this->label2->TabIndex = 14; 222 | this->label2->Text = L"Port"; 223 | // 224 | // IP 225 | // 226 | this->IP->Location = System::Drawing::Point(43, 32); 227 | this->IP->Name = L"IP"; 228 | this->IP->Size = System::Drawing::Size(94, 20); 229 | this->IP->TabIndex = 13; 230 | this->IP->Text = L"127.0.0.1"; 231 | // 232 | // label1 233 | // 234 | this->label1->AutoSize = true; 235 | this->label1->Location = System::Drawing::Point(20, 36); 236 | this->label1->Name = L"label1"; 237 | this->label1->Size = System::Drawing::Size(17, 13); 238 | this->label1->TabIndex = 12; 239 | this->label1->Text = L"IP"; 240 | // 241 | // BTNStart 242 | // 243 | this->BTNStart->Location = System::Drawing::Point(437, 31); 244 | this->BTNStart->Name = L"BTNStart"; 245 | this->BTNStart->Size = System::Drawing::Size(75, 23); 246 | this->BTNStart->TabIndex = 10; 247 | this->BTNStart->Text = L"Start"; 248 | this->BTNStart->UseVisualStyleBackColor = true; 249 | this->BTNStart->Click += gcnew System::EventHandler(this, &MyForm::BTNStart_Click); 250 | // 251 | // BTNDonwload 252 | // 253 | this->BTNDonwload->Enabled = false; 254 | this->BTNDonwload->Location = System::Drawing::Point(437, 249); 255 | this->BTNDonwload->Name = L"BTNDonwload"; 256 | this->BTNDonwload->Size = System::Drawing::Size(75, 23); 257 | this->BTNDonwload->TabIndex = 11; 258 | this->BTNDonwload->Text = L"Download"; 259 | this->BTNDonwload->UseVisualStyleBackColor = true; 260 | this->BTNDonwload->Click += gcnew System::EventHandler(this, &MyForm::BTNDonwload_Click); 261 | // 262 | // menuStrip1 263 | // 264 | this->menuStrip1->Items->AddRange(gcnew cli::array< System::Windows::Forms::ToolStripItem^ >(2) { 265 | this->fileToolStripMenuItem, 266 | this->dataModeToolStripMenuItem 267 | }); 268 | this->menuStrip1->Location = System::Drawing::Point(0, 0); 269 | this->menuStrip1->Name = L"menuStrip1"; 270 | this->menuStrip1->Size = System::Drawing::Size(523, 24); 271 | this->menuStrip1->TabIndex = 18; 272 | this->menuStrip1->Text = L"menuStrip1"; 273 | // 274 | // fileToolStripMenuItem 275 | // 276 | this->fileToolStripMenuItem->DropDownItems->AddRange(gcnew cli::array< System::Windows::Forms::ToolStripItem^ >(2) { 277 | this->ServerMode, 278 | this->ClientMode 279 | }); 280 | this->fileToolStripMenuItem->Name = L"fileToolStripMenuItem"; 281 | this->fileToolStripMenuItem->Size = System::Drawing::Size(50, 20); 282 | this->fileToolStripMenuItem->Text = L"Mode"; 283 | // 284 | // ServerMode 285 | // 286 | this->ServerMode->Checked = true; 287 | this->ServerMode->CheckState = System::Windows::Forms::CheckState::Checked; 288 | this->ServerMode->Name = L"ServerMode"; 289 | this->ServerMode->Size = System::Drawing::Size(106, 22); 290 | this->ServerMode->Text = L"Server"; 291 | this->ServerMode->Click += gcnew System::EventHandler(this, &MyForm::ServerMode_Click); 292 | // 293 | // ClientMode 294 | // 295 | this->ClientMode->Name = L"ClientMode"; 296 | this->ClientMode->Size = System::Drawing::Size(106, 22); 297 | this->ClientMode->Text = L"Client"; 298 | this->ClientMode->Click += gcnew System::EventHandler(this, &MyForm::ClientMode_Click); 299 | // 300 | // dataModeToolStripMenuItem 301 | // 302 | this->dataModeToolStripMenuItem->DropDownItems->AddRange(gcnew cli::array< System::Windows::Forms::ToolStripItem^ >(2) { 303 | this->fileToolStripMenuItem1, 304 | this->messageToolStripMenuItem 305 | }); 306 | this->dataModeToolStripMenuItem->Name = L"dataModeToolStripMenuItem"; 307 | this->dataModeToolStripMenuItem->Size = System::Drawing::Size(77, 20); 308 | this->dataModeToolStripMenuItem->Text = L"Data Mode"; 309 | // 310 | // fileToolStripMenuItem1 311 | // 312 | this->fileToolStripMenuItem1->Checked = true; 313 | this->fileToolStripMenuItem1->CheckState = System::Windows::Forms::CheckState::Checked; 314 | this->fileToolStripMenuItem1->DropDownItems->AddRange(gcnew cli::array< System::Windows::Forms::ToolStripItem^ >(1) { this->uploadToolStripMenuItem }); 315 | this->fileToolStripMenuItem1->Name = L"fileToolStripMenuItem1"; 316 | this->fileToolStripMenuItem1->Size = System::Drawing::Size(120, 22); 317 | this->fileToolStripMenuItem1->Text = L"File"; 318 | // 319 | // uploadToolStripMenuItem 320 | // 321 | this->uploadToolStripMenuItem->Name = L"uploadToolStripMenuItem"; 322 | this->uploadToolStripMenuItem->Size = System::Drawing::Size(112, 22); 323 | this->uploadToolStripMenuItem->Text = L"Upload"; 324 | this->uploadToolStripMenuItem->Click += gcnew System::EventHandler(this, &MyForm::uploadToolStripMenuItem_Click); 325 | // 326 | // messageToolStripMenuItem 327 | // 328 | this->messageToolStripMenuItem->Enabled = false; 329 | this->messageToolStripMenuItem->Name = L"messageToolStripMenuItem"; 330 | this->messageToolStripMenuItem->Size = System::Drawing::Size(120, 22); 331 | this->messageToolStripMenuItem->Text = L"Message"; 332 | // 333 | // QueueList 334 | // 335 | this->QueueList->Columns->AddRange(gcnew cli::array< System::Windows::Forms::ColumnHeader^ >(6) { 336 | this->ID, this->FileName, 337 | this->FileExtention, this->Condition, this->DateTime, this->QueueType 338 | }); 339 | this->QueueList->HideSelection = false; 340 | this->QueueList->Location = System::Drawing::Point(12, 71); 341 | this->QueueList->Name = L"QueueList"; 342 | this->QueueList->Size = System::Drawing::Size(500, 172); 343 | this->QueueList->TabIndex = 9; 344 | this->QueueList->UseCompatibleStateImageBehavior = false; 345 | this->QueueList->View = System::Windows::Forms::View::Details; 346 | this->QueueList->SelectedIndexChanged += gcnew System::EventHandler(this, &MyForm::QueueList_SelectedIndexChanged); 347 | // 348 | // ID 349 | // 350 | this->ID->Text = L"ID"; 351 | this->ID->Width = 41; 352 | // 353 | // FileName 354 | // 355 | this->FileName->Text = L"Name"; 356 | this->FileName->Width = 96; 357 | // 358 | // FileExtention 359 | // 360 | this->FileExtention->Text = L"Extention"; 361 | this->FileExtention->Width = 70; 362 | // 363 | // Condition 364 | // 365 | this->Condition->Text = L"Condition"; 366 | this->Condition->Width = 88; 367 | // 368 | // DateTime 369 | // 370 | this->DateTime->Text = L"Date and Time"; 371 | this->DateTime->Width = 106; 372 | // 373 | // QueueType 374 | // 375 | this->QueueType->Text = L"QueueType"; 376 | this->QueueType->Width = 82; 377 | // 378 | // MyForm 379 | // 380 | this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Inherit; 381 | this->AutoScroll = true; 382 | this->ClientSize = System::Drawing::Size(523, 284); 383 | this->Controls->Add(this->IP); 384 | this->Controls->Add(this->menuStrip1); 385 | this->Controls->Add(this->QueueList); 386 | this->Controls->Add(this->BTNDonwload); 387 | this->Controls->Add(this->PBTreansfered); 388 | this->Controls->Add(this->label2); 389 | this->Controls->Add(this->BTNStart); 390 | this->Controls->Add(this->Port); 391 | this->Controls->Add(this->Clients); 392 | this->Controls->Add(this->label1); 393 | this->FormBorderStyle = System::Windows::Forms::FormBorderStyle::FixedSingle; 394 | this->HelpButton = true; 395 | this->MaximizeBox = false; 396 | this->Text = L"Server"; 397 | this->menuStrip1->ResumeLayout(false); 398 | this->menuStrip1->PerformLayout(); 399 | this->ResumeLayout(false); 400 | this->PerformLayout(); 401 | 402 | } 403 | #pragma endregion 404 | std::string to_stirng(String^ str) 405 | { 406 | msclr::interop::marshal_context contex; 407 | return contex.marshal_as(str); 408 | } 409 | void AddClient(String^ Username , bool flag) 410 | { 411 | if (flag) 412 | { 413 | if (this->InvokeRequired) 414 | { 415 | this->Invoke(Event_ADDCLIENT, Username, flag); 416 | return; 417 | } 418 | Clients->Items->Add(Username); 419 | } 420 | else 421 | { 422 | if (this->InvokeRequired) 423 | this->Invoke(Event_ADDCLIENT, Username, flag); 424 | Clients->Items->Remove(Username); 425 | } 426 | 427 | 428 | } 429 | void ChangeClient(std::string username , bool flag) 430 | { 431 | AddClient(gcnew String(username.c_str()) , flag); 432 | } 433 | void AddNewQueue(array^ row) 434 | { 435 | if (this->InvokeRequired) 436 | { 437 | this->Invoke(Event_ADDQUEUE, gcnew array { row }); 438 | return; 439 | } 440 | ListViewItem^ item = gcnew ListViewItem(row); 441 | QueueList->Items->Add(item); 442 | } 443 | void NewQueueRow(int Queueid , String^ Name , String^ Extention) 444 | { 445 | array^ row = { Queueid.ToString() , Name , Extention , "0" , DateTime::Now.ToString() , "Upload" }; 446 | AddNewQueue(row); 447 | } 448 | void NewQueueRow(int Queueid, std::string Name, std::string Extention) 449 | { 450 | array^ row = { Queueid.ToString() , gcnew String(Name.c_str()) , gcnew String(Extention.c_str()) , "0" , DateTime::Now.ToString() , "Download" }; 451 | Event_ADDQUEUE(row); 452 | } 453 | void CompeleteTransfer(int Queueid) 454 | { 455 | if (this->InvokeRequired) 456 | { 457 | this->Invoke(Event_Compelete, Queueid); 458 | return; 459 | } 460 | IsTransfer = false; 461 | for each (ListViewItem^ var in QueueList->Items) 462 | { 463 | if (var->SubItems[0]->Text == Queueid.ToString()) 464 | var->SubItems[3]->Text = "1"; 465 | } 466 | } 467 | private: System::Void ClientMode_Click(System::Object^ sender, System::EventArgs^ e) { 468 | ServerMode->Checked = false; 469 | ClientMode->Checked = true; 470 | Clients->Visible = false; 471 | BTNStart->Text = "Connect"; 472 | } 473 | private: System::Void ServerMode_Click(System::Object^ sender, System::EventArgs^ e) { 474 | ServerMode->Checked = true; 475 | ClientMode->Checked = false; 476 | Clients->Visible = true; 477 | BTNStart->Text = "Start"; 478 | } 479 | void StartServer() 480 | { 481 | std::string ip = to_stirng(IP->Text); 482 | int port = Convert::ToInt32(Port->Text); 483 | IsRunning = true; 484 | Startup(ip, port, Event_UIChangeProgress, Event_UINewClient, Event_UINewRecieve); 485 | } 486 | private: System::Void uploadToolStripMenuItem_Click(System::Object^ sender, System::EventArgs^ e) { 487 | try 488 | { 489 | if (IsRunning && !IsTransfer) 490 | { 491 | OpenFileDialog^ ofd = gcnew OpenFileDialog(); 492 | ofd->Multiselect = false; 493 | ofd->CheckFileExists = true; 494 | ofd->CheckPathExists = true; 495 | ofd->Title = "Uplaod File"; 496 | if (ofd->ShowDialog() == System::Windows::Forms::DialogResult::OK) 497 | { 498 | try 499 | { 500 | std::string path = to_stirng(ofd->FileName); 501 | int queueid = SendFile(path , to_stirng(Clients->SelectedItem->ToString())); 502 | IsTransfer = true; 503 | NewQueueRow(queueid , Path::GetFileNameWithoutExtension(ofd->FileName) , Path::GetExtension(ofd->FileName)); 504 | } 505 | catch (const std::exception& ex) 506 | { 507 | throw gcnew Exception(gcnew String(ex.what())); 508 | } 509 | 510 | } 511 | } 512 | } 513 | catch (Exception^ ex) 514 | { 515 | MessageBox::Show(ex->Message); 516 | } 517 | } 518 | 519 | private: System::Void BTNStart_Click(System::Object^ sender, System::EventArgs^ e) { 520 | Thread^ thread = gcnew Thread(gcnew ThreadStart(this , &MyForm::StartServer)); 521 | thread->Start(); 522 | BTNStart->Enabled = false; 523 | } 524 | private: System::Void QueueList_SelectedIndexChanged(System::Object^ sender, System::EventArgs^ e) { 525 | if ((((ListView^)sender)->SelectedItems->Count == 1) && IsRunning && !IsTransfer) 526 | { 527 | ListViewItem^ item = ((ListView^)sender)->SelectedItems[0]; 528 | if (item->SubItems[5]->Text == "Download" && item->SubItems[3]->Text == "0") 529 | { 530 | BTNDonwload->Enabled = true; 531 | } 532 | else 533 | BTNDonwload->Enabled = false; 534 | } 535 | else 536 | BTNDonwload->Enabled = false; 537 | } 538 | void ChangeProgress(int queuid , int value) 539 | { 540 | if (this->InvokeRequired) 541 | this->Invoke(Event_Progress , queuid , value); 542 | PBTreansfered->Value = value; 543 | if (PBTreansfered->Value == 100) 544 | CompeleteTransfer(queuid); 545 | 546 | } 547 | private: System::Void BTNDonwload_Click(System::Object^ sender, System::EventArgs^ e) { 548 | BTNDonwload->Enabled = false; 549 | int queueid = Convert::ToInt32(QueueList->SelectedItems[0]->SubItems[0]->Text); 550 | StartDownload(queueid); 551 | } 552 | }; 553 | } 554 | -------------------------------------------------------------------------------- /TCP/StepByStep/E04-Final/SocketUI/MyForm.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 17, 17 122 | 123 | -------------------------------------------------------------------------------- /TCP/StepByStep/E04-Final/SocketUI/SocketUI.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.31205.134 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SocketUI", "SocketUI.vcxproj", "{17F30EFF-AEF1-48E6-8EA1-97801C90A10B}" 7 | EndProject 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ServerDLL", "..\ServerDLL\ServerDLL.vcxproj", "{5281063A-F0D8-4F30-B291-DD2A8D9E4425}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|x64 = Debug|x64 13 | Debug|x86 = Debug|x86 14 | Release|x64 = Release|x64 15 | Release|x86 = Release|x86 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {17F30EFF-AEF1-48E6-8EA1-97801C90A10B}.Debug|x64.ActiveCfg = Debug|x64 19 | {17F30EFF-AEF1-48E6-8EA1-97801C90A10B}.Debug|x64.Build.0 = Debug|x64 20 | {17F30EFF-AEF1-48E6-8EA1-97801C90A10B}.Debug|x86.ActiveCfg = Debug|Win32 21 | {17F30EFF-AEF1-48E6-8EA1-97801C90A10B}.Debug|x86.Build.0 = Debug|Win32 22 | {17F30EFF-AEF1-48E6-8EA1-97801C90A10B}.Release|x64.ActiveCfg = Release|x64 23 | {17F30EFF-AEF1-48E6-8EA1-97801C90A10B}.Release|x64.Build.0 = Release|x64 24 | {17F30EFF-AEF1-48E6-8EA1-97801C90A10B}.Release|x86.ActiveCfg = Release|Win32 25 | {17F30EFF-AEF1-48E6-8EA1-97801C90A10B}.Release|x86.Build.0 = Release|Win32 26 | {5281063A-F0D8-4F30-B291-DD2A8D9E4425}.Debug|x64.ActiveCfg = Debug|x64 27 | {5281063A-F0D8-4F30-B291-DD2A8D9E4425}.Debug|x64.Build.0 = Debug|x64 28 | {5281063A-F0D8-4F30-B291-DD2A8D9E4425}.Debug|x86.ActiveCfg = Debug|Win32 29 | {5281063A-F0D8-4F30-B291-DD2A8D9E4425}.Debug|x86.Build.0 = Debug|Win32 30 | {5281063A-F0D8-4F30-B291-DD2A8D9E4425}.Release|x64.ActiveCfg = Release|x64 31 | {5281063A-F0D8-4F30-B291-DD2A8D9E4425}.Release|x64.Build.0 = Release|x64 32 | {5281063A-F0D8-4F30-B291-DD2A8D9E4425}.Release|x86.ActiveCfg = Release|Win32 33 | {5281063A-F0D8-4F30-B291-DD2A8D9E4425}.Release|x86.Build.0 = Release|Win32 34 | EndGlobalSection 35 | GlobalSection(SolutionProperties) = preSolution 36 | HideSolutionNode = FALSE 37 | EndGlobalSection 38 | GlobalSection(ExtensibilityGlobals) = postSolution 39 | SolutionGuid = {C2CE2C2B-1876-47DD-9B55-F499CF2D8404} 40 | EndGlobalSection 41 | EndGlobal 42 | -------------------------------------------------------------------------------- /TCP/StepByStep/E04-Final/SocketUI/SocketUI.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 16.0 23 | {17F30EFF-AEF1-48E6-8EA1-97801C90A10B} 24 | v4.7.2 25 | ManagedCProj 26 | SocketUI 27 | 10.0 28 | 29 | 30 | 31 | Application 32 | true 33 | v142 34 | true 35 | Unicode 36 | 37 | 38 | Application 39 | false 40 | v142 41 | true 42 | Unicode 43 | 44 | 45 | Application 46 | true 47 | v142 48 | true 49 | Unicode 50 | 51 | 52 | Application 53 | false 54 | v142 55 | true 56 | Unicode 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | Level3 80 | WIN32;_DEBUG;%(PreprocessorDefinitions) 81 | 82 | 83 | 84 | Windows 85 | Main 86 | 87 | 88 | 89 | 90 | Level3 91 | _DEBUG;%(PreprocessorDefinitions) 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | Level3 100 | WIN32;NDEBUG;%(PreprocessorDefinitions) 101 | 102 | 103 | 104 | Windows 105 | Main 106 | 107 | 108 | 109 | 110 | Level3 111 | NDEBUG;%(PreprocessorDefinitions) 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | CppForm 131 | 132 | 133 | 134 | 135 | MyForm.h 136 | 137 | 138 | 139 | 140 | 141 | -------------------------------------------------------------------------------- /TCP/StepByStep/E04-Final/SocketUI/SocketUI.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | 24 | Header Files 25 | 26 | 27 | -------------------------------------------------------------------------------- /TCP/StepByStep/E04-Final/SocketUI/SocketUI.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | --------------------------------------------------------------------------------