안녕하세요. 언제나 휴일에 언휴예요.
이번 강의는 파일 전송 클라이언트를 구현하는 실습입니다.
1. 파일 데이터 전송 이벤트 인자 및 대리자 구현
using System; namespace 파일_전송_클라이언트 { public delegate void SendFileDataEventHandler(object sender, SendFileDataEventArgs e); public class SendFileDataEventArgs:EventArgs { public string FileName { get; private set; } public long Remain { get; private set; } public SendFileDataEventArgs(string fname, long remain) { FileName = fname; Remain = remain; } } }
2. 파일 전송 클라이언트 클래스 구현
/* https://ehpub.co.kr * 파일 전송 클라이언트 */ using System; using System.IO; using System.Net; using System.Net.Sockets; using System.Security.Cryptography; namespace 파일_전송_클라이언트 { public class FileSendClient { const int MAX_PACK_SIZE = 1024; public event SendFileDataEventHandler SendFileDataEventHandler = null; public string IPStr { get; private set; } public int Port { get; private set; } public FileSendClient(string ip, int port) { IPStr = ip; Port = port; } delegate void SendDele(string fname); public void SendAsync(string fname) { SendDele dele = Send; dele.BeginInvoke(fname, null, null); } public void Send(string fname) { if(File.Exists(fname)==false) { return; } Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); IPEndPoint iep = new IPEndPoint(IPAddress.Parse(IPStr), Port); sock.Connect(iep); byte[] packet = new byte[MAX_PACK_SIZE]; MemoryStream ms = new MemoryStream(packet); BinaryWriter bw = new BinaryWriter(ms); bw.Write(fname); bw.Close(); ms.Close(); sock.Send(packet); FileStream fs = File.OpenRead(fname); ms = new MemoryStream(packet); bw = new BinaryWriter(ms); bw.Write(fs.Length); sock.Send(packet, 0, 8, SocketFlags.None); ms.Close(); bw.Close(); long remain = fs.Length; int sl; while(remain>=MAX_PACK_SIZE) { fs.Read(packet, 0, MAX_PACK_SIZE); sl = sock.Send(packet); while(sl<MAX_PACK_SIZE) { sl += sock.Send(packet, sl, MAX_PACK_SIZE - sl, SocketFlags.None); } if(SendFileDataEventHandler != null) { SendFileDataEventHandler(this, new SendFileDataEventArgs(fname, remain)); } remain -= MAX_PACK_SIZE; } fs.Read(packet, 0, (int)remain); sl = sock.Send(packet); while (sl < remain) { sl += sock.Send(packet, sl, (int)remain - sl, SocketFlags.None); } remain = 0; if (SendFileDataEventHandler != null) { SendFileDataEventHandler(this, new SendFileDataEventArgs(fname, remain)); } fs.Close(); sock.Close(); } } }
3. Program.cs 에서 사용
/* https://ehpub.co.kr * 파일 전송 클라이언트 */ using System; namespace 파일_전송_클라이언트 { class Program { static void Main(string[] args) { Console.Write("서버 IP:"); string ip = Console.ReadLine(); int port = 10340; Console.Write("포트 번호:{0}",port); FileSendClient fsc = new FileSendClient(ip, port); fsc.SendFileDataEventHandler += Fsc_SendFileDataEventHandler; Console.Write("전송할 파일명:"); string fname = Console.ReadLine(); fsc.SendAsync(fname); Console.ReadKey(); } private static void Fsc_SendFileDataEventHandler(object sender, SendFileDataEventArgs e) { Console.WriteLine("{0}파일 {1}bytes 남았음.", e.FileName, e.Remain); } } }