Advertisement
Guest User

Untitled

a guest
Jan 21st, 2020
63
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 20.59 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.IO;
  5. using System.Net;
  6. using System.Net.Sockets;
  7. using System.Security.Cryptography;
  8. using System.Text;
  9. using System.Threading;
  10. using System.Windows.Forms;
  11.  
  12. namespace FileSenderGUI
  13. {
  14. public partial class Window : Form
  15. {
  16. public Window()
  17. {
  18. InitializeComponent();
  19. //get settings
  20. settings_serverAddressInput.Text = Properties.Settings.Default.ServerAddress;
  21. settings_serverPortInput.Value = Properties.Settings.Default.ServerPort;
  22. settings_listenPortInput.Value = Properties.Settings.Default.ListenPort;
  23. }
  24.  
  25. //send tab
  26. private string send_filename;
  27.  
  28. private FileInfo send_fileinfo;
  29. private string send_hash;
  30. private TcpClient send_tcpclient;
  31. private Thread send_connectthread;
  32. private Thread send_checksum;
  33.  
  34. private void send_updateStatus(string status)
  35. {
  36. //append the string to a newline and automatically scroll down to the bottom.
  37. this.InvokeEx(f => send_Status.Text += "\r\n" + status);
  38. this.InvokeEx(f => send_Status.SelectionStart = send_Status.Text.Length);
  39. this.InvokeEx(f => send_Status.ScrollToCaret());
  40. }
  41.  
  42. private void send_fileSelectButton_Click(object sender, EventArgs e)
  43. {
  44. //select file
  45. send_fileSelect.ShowDialog();
  46. send_filename = send_fileSelect.FileName;
  47.  
  48. //if a file was selected, generate checksum of file and get fileinfo.
  49. if (send_filename != "")
  50. {
  51. send_fileinfo = new FileInfo(send_filename);
  52. send_updateStatus("Computing file checksum...");
  53. send_checksum = new Thread(send_computehash);
  54. send_checksum.Start();
  55. send_checksum.Join();
  56. send_updateStatus("File selected.");
  57. }
  58. }
  59.  
  60. private void send_computehash()
  61. {
  62. send_hash = methods.checkMD5(send_filename);
  63. }
  64.  
  65. private void send_sendButton_Click(object sender, EventArgs e)
  66. {
  67. send_connectthread = new Thread(send);
  68. //check that a file has been selected
  69. if (send_filename == null) { send_updateStatus("Error: No file selected"); }
  70. else
  71. {
  72. //check if the send thread is already running. if so, abort the thread. if not, start the thread.
  73. if (send_connectthread.IsAlive)
  74. {
  75. //stop
  76. send_connectthread.Abort();
  77. send_sendButton.Text = "Send";
  78. }
  79. else
  80. {
  81. //start
  82. try
  83. {
  84. //check if thread died; if so dispose the old, useless one and create a new one.
  85. if (send_connectthread.ThreadState == ThreadState.Stopped || send_connectthread.ThreadState == ThreadState.Aborted)
  86. {
  87. send_connectthread = new Thread(send);
  88. }
  89. send_connectthread.Start();
  90. send_sendButton.Text = "Cancel";
  91. }
  92. catch (Exception err)
  93. {
  94. send_updateStatus("Error starting send thread: " + err.Message);
  95. send_sendButton.Text = "Send";
  96. }
  97. }
  98. }
  99. }
  100.  
  101. private void send()
  102. {
  103. send_updateStatus("Connecting...");
  104. try
  105. {
  106. clientdisconnect();
  107. //create new client object
  108. send_tcpclient = new TcpClient();
  109.  
  110. //connect to the server
  111. send_tcpclient.Connect(Properties.Settings.Default.ServerAddress, Properties.Settings.Default.ServerPort);
  112. send_updateStatus("Connected. Waiting for remote approval...");
  113.  
  114. //communication protocol handler
  115. send_tcpclient.Client.Send(Encoding.ASCII.GetBytes(send_fileinfo.Length + "," + send_hash + "," + send_fileinfo.Name + "\n"));
  116. //read the response from the client to determine whether to send the file or not
  117. string data;
  118. //while socket is connected:
  119. try
  120. {
  121. for (; ; )
  122. {
  123. var data_bytes = methods.ReceiveAll(send_tcpclient.Client);
  124. data = Encoding.UTF8.GetString(data_bytes, 0, data_bytes.Length);
  125. if (data.Length != 0)
  126. {
  127. //remove pesky return at the end
  128. data = data.Remove(data.Length - 1, 1);
  129. //we now have the response; exit the loop.
  130. break;
  131. }
  132. if (!methods.IsConnected(send_tcpclient.Client))
  133. {
  134. send_updateStatus("Server disconnected.");
  135. this.InvokeEx(f => send_sendButton.Text = "Send");
  136. send_tcpclient.Dispose();
  137. return;
  138. }
  139. }
  140. }
  141. catch
  142. {
  143. send_updateStatus("Error receiving response from server.");
  144. try { send_tcpclient.Close(); } catch { }
  145. send_tcpclient.Dispose();
  146. return;
  147. }
  148.  
  149. //have they accepted the file?
  150. if (data == "ACCEPT_FILE")
  151. {
  152. send_updateStatus("File accepted. Sending...");
  153.  
  154. //configure progress bar
  155. int total = 0;
  156. this.InvokeEx(f => send_progressBar.Maximum = (int)send_fileinfo.Length);
  157.  
  158. var readed = -1;
  159. var buffer = new Byte[4096];
  160. using (var networkStream = new BufferedStream(new NetworkStream(send_tcpclient.Client, false)))
  161. using (var fileStream = send_fileinfo.OpenRead())
  162. {
  163. while (readed != 0)
  164. {
  165. readed = fileStream.Read(buffer, 0, buffer.Length);
  166. networkStream.Write(buffer, 0, readed);
  167.  
  168. //update progress bar
  169. total = total + readed;
  170. this.InvokeEx(f => send_progressBar.Value = total);
  171. }
  172. networkStream.FlushAsync();
  173. }
  174. send_updateStatus("File send complete.");
  175. }
  176. else if (data == "DENY_FILE") { send_updateStatus("File rejected. Aborting send..."); }
  177. else
  178. {
  179. send_updateStatus("Protocol error! Received '" + data + "' as a response");
  180. send_tcpclient.Client.Send(Encoding.ASCII.GetBytes("Protocol error! Disconnecting."));
  181. }
  182.  
  183. //at this point we should disconnect.
  184. clientdisconnect();
  185. this.InvokeEx(f => send_sendButton.Text = "Send");
  186. send_updateStatus("Disconnected.");
  187. }
  188. catch (Exception err)
  189. {
  190. send_updateStatus("Error connecting: " + err.Message);
  191. this.InvokeEx(f => send_sendButton.Text = "Send");
  192. }
  193. }
  194.  
  195. private void clientdisconnect()
  196. {
  197. //attempt to disconnect the connection
  198. try
  199. {
  200. send_tcpclient.Client.Disconnect(true);
  201. send_tcpclient.Close();
  202. send_tcpclient.Dispose();
  203. }
  204. catch { }
  205. }
  206.  
  207. //receive tab
  208. private string receive_foldername;
  209.  
  210. private string receive_filename;
  211. private string receive_filehash;
  212. private string receive_hash;
  213. private Int64 receive_filesize;
  214. private TcpListener receive_listener;
  215. private Socket receive_socket;
  216. private Thread receivethread;
  217. private Thread receive_checksum;
  218. private bool receive_isserverrunning = false;
  219.  
  220. public string Receive_filehash { get => receive_filehash; set => receive_filehash = value; }
  221.  
  222. private void Receive_disconnect()
  223. {
  224. try { receive_socket.Disconnect(false); }
  225. catch { }
  226. try { receive_socket.Dispose(); }
  227. catch { }
  228. try { receive_listener.Stop(); }
  229. catch { }
  230. }
  231.  
  232. private void receive_updateStatus(string status)
  233. {
  234. //append the string to a newline and automatically scroll down to the bottom.
  235. this.InvokeEx(f => receive_Status.Text += "\r\n" + status);
  236. this.InvokeEx(f => receive_Status.SelectionStart = receive_Status.Text.Length);
  237. this.InvokeEx(f => receive_Status.ScrollToCaret());
  238. }
  239.  
  240. private void Receive_computehash()
  241. {
  242. receive_hash = methods.checkMD5(receive_foldername + @"\" + receive_filename);
  243. }
  244.  
  245. private void Receive_selectFolderButton_Click(object sender, EventArgs e)
  246. {
  247. receive_selectFolder.ShowDialog();
  248. if (receive_selectFolder.SelectedPath != "")
  249. {
  250. receive_foldername = receive_selectFolder.SelectedPath;
  251. receive_startServerButton.Enabled = true;
  252. receive_updateStatus("Set folder path to " + receive_foldername);
  253. }
  254. }
  255.  
  256. private void Receive_startServerButton_Click(object sender, EventArgs e)
  257. {
  258. if (receive_isserverrunning)
  259. {
  260. Receive_disconnect();
  261. receivethread.Abort();
  262. receive_startServerButton.Text = "Start server";
  263. receive_updateStatus("Stopped server.");
  264. receive_isserverrunning = false;
  265. receive_progressBar.Value = 0;
  266. }
  267. else
  268. {
  269. receive_startServerButton.Text = "Stop server";
  270. receive_updateStatus("Started server.");
  271. receive_isserverrunning = true;
  272. receivethread = new Thread(Recv);
  273. receivethread.Start();
  274. }
  275. }
  276.  
  277. public void Recv()
  278. {
  279. try
  280. {
  281. receive_listener = new TcpListener(IPAddress.Any, Properties.Settings.Default.ListenPort);
  282. receive_listener.Start();
  283. receive_updateStatus("Listening for file transfer requests on port " + Convert.ToString(Properties.Settings.Default.ListenPort));
  284. receive_socket = receive_listener.AcceptSocket();
  285.  
  286. IPEndPoint remoteIpEndPoint = receive_socket.RemoteEndPoint as IPEndPoint; //create way of getting addresses
  287.  
  288. receive_updateStatus("Connection established from " + remoteIpEndPoint.Address + "\n");
  289. //socket is now connected.
  290. for (; ; )
  291. {
  292. //while socket is connected:
  293. try
  294. {
  295. var data_bytes = methods.ReceiveAll(receive_socket);
  296. string data = Encoding.UTF8.GetString(data_bytes, 0, data_bytes.Length);
  297. if (data.Length != 0)
  298. {
  299. //remove pesky return at the end
  300. data = data.Remove(data.Length - 1, 1); //data structure is as follows: length in bytes, file hash, filename
  301. //split data by commas.
  302. string[] res = data.Split(Convert.ToChar(","));
  303. //put each part of the array into variables
  304. receive_filesize = Convert.ToInt64(res[0]);
  305. receive_filehash = res[1];
  306. receive_filename = res[2];
  307. //display prompt to alert user of incoming file. since we want to act upon the response, we store the result to a DialogResult.
  308. DialogResult dlgResult = MessageBox.Show("Filesize: " + methods.filesizePerpective(receive_filesize) + "\nFile hash: " + receive_filehash + "\nFilename: " + receive_filename + "\n\nAccept the file?", "Incoming file request", MessageBoxButtons.YesNo);
  309. if (dlgResult == DialogResult.Yes)
  310. {
  311. //configure progress bar
  312. int total = 0;
  313. this.InvokeEx(f => receive_progressBar.Maximum = (int)receive_filesize + 4000);
  314.  
  315. //reply to sender with confirmation
  316. receive_socket.Send(Encoding.ASCII.GetBytes("ACCEPT_FILE\n"));
  317.  
  318. //begin receiving the file, writing it into a filestream.
  319. FileInfo file = new FileInfo(receive_foldername + @"\" + receive_filename);
  320. var readed = -1;
  321. var buffer = new Byte[4096];
  322. using (var fileStream = file.OpenWrite())
  323. using (var networkStream = new NetworkStream(receive_socket, false))
  324. {
  325. while (readed != 0)
  326. {
  327. readed = networkStream.Read(buffer, 0, buffer.Length);
  328. fileStream.Write(buffer, 0, readed);
  329.  
  330. //update progress bar
  331. total = total + readed;
  332. this.InvokeEx(f => receive_progressBar.Value = total);
  333. }
  334. }
  335.  
  336. //now we have the file, we should disconnect.
  337. try { Receive_disconnect(); }
  338. catch { }
  339.  
  340. //check filehash of received file
  341. receive_updateStatus("File downloaded.\nVerifying file integrity...");
  342. receive_checksum = new Thread(Receive_computehash);
  343. receive_checksum.Start();
  344. receive_checksum.Join();
  345. if (receive_filehash != receive_hash)
  346. {
  347. receive_updateStatus("Detected mismatching hash files.");
  348. MessageBox.Show("Warning! \n\nThe hash of the downloaded file doesn't match the original! This could be an indication of a corrupted file.\nOriginal hash: " + receive_filehash + "\nHash of downloaded file: " + receive_hash, "Warning", MessageBoxButtons.OK);
  349. }
  350. else { receive_updateStatus("File integrity verified."); }
  351. }
  352. else { receive_socket.Send(Encoding.ASCII.GetBytes("DENY_FILE")); }
  353. }
  354. if (!methods.IsConnected(receive_socket))
  355. {
  356. receive_updateStatus("Sender disconnected.");
  357. receive_startServerButton.Text = "Start server";
  358. receive_isserverrunning = false;
  359. break;
  360. }
  361. }
  362. catch (Exception err)
  363. {
  364. if (methods.IsConnected(receive_socket))
  365. {
  366. receive_updateStatus("Error receiving file data:\n" + err.Message);
  367. try { Receive_disconnect(); }
  368. catch { }
  369. }
  370. }
  371. }
  372. }
  373. catch (Exception err)
  374. {
  375. if (err.Message == "Thread was being aborted.") { }
  376. else if (err.Message.Contains("disposed object")) { }
  377. else { receive_updateStatus("Error hosting server: " + err.Message); }
  378. }
  379. }
  380.  
  381. //settings tab
  382. private void settings_saveSettingsButton_Click(object sender, EventArgs e)
  383. {
  384. //save settings to appdata
  385. Properties.Settings.Default.ServerAddress = settings_serverAddressInput.Text;
  386. Properties.Settings.Default.ServerPort = Convert.ToInt32(settings_serverPortInput.Value);
  387. Properties.Settings.Default.ListenPort = Convert.ToInt32(settings_listenPortInput.Value);
  388. Properties.Settings.Default.Save();
  389. }
  390. }
  391.  
  392. internal static class methods
  393. {
  394. public static bool IsConnected(this Socket socket)
  395. {
  396. try { return !(socket.Poll(1, SelectMode.SelectRead) && socket.Available == 0); }
  397. catch (SocketException) { return false; }
  398. }
  399.  
  400. public static byte[] ReceiveAll(this Socket socket)
  401. {
  402. var buffer = new List<byte>();
  403. while (socket.Available > 0)
  404. {
  405. var currByte = new Byte[1];
  406. var byteCounter = socket.Receive(currByte, currByte.Length, SocketFlags.None);
  407.  
  408. if (byteCounter.Equals(1)) { buffer.Add(currByte[0]); }
  409. }
  410. return buffer.ToArray();
  411. }
  412.  
  413. public static string checkMD5(string filename)
  414. {
  415. using (var md5 = MD5.Create())
  416. {
  417. using (var stream = File.OpenRead(filename))
  418. {
  419. return BitConverter.ToString(md5.ComputeHash(stream)).Replace("-", "").ToLowerInvariant();
  420. }
  421. }
  422. }
  423.  
  424. public static string filesizePerpective(Int64 filesize)
  425. {
  426. int kilobyte_size = 1024;
  427. int megabyte_size = 1024000;
  428. int gigabyte_size = 1024000000;
  429. //Int64 is needed due to the numbers being way too big for 32 bit .-.
  430. Int64 terabyte_size = Convert.ToInt64(1024000000000);
  431. string size;
  432.  
  433. try
  434. {
  435. //Calculate file size. Uses kilobytes, megabytes, gigabytes and even terabytes.
  436. if (filesize > terabyte_size)
  437. {
  438. //Terabytes
  439. float formatted_size = filesize / terabyte_size;
  440. size = (formatted_size.ToString() + " TB (" + filesize + " bytes)");
  441. }
  442. else if (filesize > gigabyte_size)
  443. {
  444. //Gigabytes
  445. float formatted_size = filesize / gigabyte_size;
  446. size = (formatted_size.ToString() + " GB (" + filesize + " bytes)");
  447. }
  448. else if (filesize > megabyte_size)
  449. {
  450. //Megabytes
  451. float formatted_size = filesize / megabyte_size;
  452. size = (formatted_size.ToString() + " MB (" + filesize + " bytes)");
  453. }
  454. else if (filesize > kilobyte_size)
  455. {
  456. //Kilobytes
  457. float formatted_size = filesize / kilobyte_size;
  458. size = (formatted_size.ToString() + " KB (" + filesize + " bytes)");
  459. }
  460. else
  461. {
  462. //Bytes
  463. size = (filesize + " bytes");
  464. }
  465. }
  466. catch (DivideByZeroException) { size = "0 bytes"; }
  467. return size;
  468. }
  469. }
  470.  
  471. internal static class ISynchronizeInvokeExtensions
  472. {
  473. public static void InvokeEx<T>(this T @this, Action<T> action) where T : ISynchronizeInvoke
  474. {
  475. if (@this.InvokeRequired)
  476. {
  477. @this.Invoke(action, new object[] { @this });
  478. }
  479. else
  480. {
  481. action(@this);
  482. }
  483. }
  484. }
  485. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement