2015. 3. 26. 13:45
C# with TCP/IP
프로그램 설명
바이트 배열을 이용한 파일 전송을 구현한 예시입니다.
이미지 파일 전송시 데이타 구조와 일반 텍스트 데이타 구조가 다르므로 아래에 그림으로 표시했습니다.
실행 후
이미지 파일 전송 후
메시지 전송 후
프로그램 작성
1. 데이타 버퍼 클래스 (StateObject.cs)
class StateObject { // Client socket public Socket workSocket = null; public const int BufferSize = 4096; // Receive buffer public byte[] buffer = new byte[BufferSize]; }
2. 서버 프로그램
public partial class MainForm : Form { bool initialFlag = true; string receivedPath = string.Empty; enum DataPacketType { TEXT = 1, IMAGE }; int dataType = 0; string textData = string.Empty; public MainForm() { InitializeComponent(); Thread t_handler = new Thread(StartListening); t_handler.IsBackground = true; t_handler.Start(); } public static ManualResetEvent allDone = new ManualResetEvent(false); private void StartListening() { IPEndPoint localEP = new IPEndPoint(IPAddress.Any, 9050); Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); try { listener.Bind(localEP); listener.Listen(10); while(true) { allDone.Reset(); listener.BeginAccept(new AsyncCallback(AcceptCallback), listener); allDone.WaitOne(); } } catch(SocketException se) { Trace.WriteLine(string.Format("SocketException :{0}", se.Message)); } catch(Exception ex) { Trace.WriteLine(string.Format("Exception :{0}", ex.Message)); } } private void AcceptCallback(IAsyncResult ar) { allDone.Set(); Socket listener = ar.AsyncState as Socket; Socket handler = listener.EndAccept(ar); StateObject state = new StateObject(); state.workSocket = handler; handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state); initialFlag = true; } private void ReadCallback(IAsyncResult ar) { int fileNameLen = 0; string content = string.Empty; StateObject state = ar.AsyncState as StateObject; Socket handler = state.workSocket; int bytesRead = handler.EndReceive(ar); if(bytesRead > 0) { if (initialFlag) { dataType = BitConverter.ToInt32(state.buffer, 0); if (dataType == (int)DataPacketType.IMAGE) { fileNameLen = BitConverter.ToInt32(state.buffer, 4); string fileName = Encoding.UTF8.GetString(state.buffer, 8, fileNameLen); string pathUser = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); string pathDownload = Path.Combine(pathUser, "Downloads"); receivedPath = Path.Combine(pathDownload, fileName); if (File.Exists(receivedPath)) File.Delete(receivedPath); } else if (dataType == (int)DataPacketType.TEXT) { textData = Encoding.UTF8.GetString(state.buffer, 4, bytesRead - 4); handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state); } } if (dataType == (int)DataPacketType.IMAGE) { BinaryWriter bw = new BinaryWriter(File.Open(receivedPath, FileMode.Append)); if (initialFlag) bw.Write(state.buffer, 8 + fileNameLen, bytesRead - (8 + fileNameLen)); else bw.Write(state.buffer, 0, bytesRead); initialFlag = false; bw.Close(); handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state); } } else { if (dataType == (int)DataPacketType.IMAGE) { pictureBox1.ImageLocation = receivedPath; Invoke((MethodInvoker)delegate { lblMessage.Text = "Data has been received"; }); } else if (dataType == (int)DataPacketType.TEXT) Invoke((MethodInvoker)delegate { textBox1.AppendText(textData + Environment.NewLine); }); } } }
3. 클라이언트 프로그램
public partial class MainForm : Form { string m_splitter = "'\\'"; string m_fName = string.Empty; string[] m_split = null; byte[] m_clientData = null; enum DataPacketType { TEXT = 1, IMAGE }; public MainForm() { InitializeComponent(); } private void btnBrowse_Click(object sender, EventArgs e) { char[] delimeter = m_splitter.ToCharArray(); openFileDialog1.Filter = "Image files (*.jpg, *.jpeg, *.jpe, *.jfif, *.png) | *.jpg; *.jpeg; *.jpe; *.jfif; *.png"; openFileDialog1.ShowDialog(); textBox1.Text = openFileDialog1.FileName; pictureBox1.ImageLocation = openFileDialog1.FileName; m_split = textBox1.Text.Split(delimeter); int limit = m_split.Length; m_fName = m_split[limit - 1].ToString(); if (textBox1.Text != null) btnSend.Enabled = true; } private void btnSend_Click(object sender, EventArgs e) { Thread t_handler = new Thread(SendData); t_handler.IsBackground = true; t_handler.Start(); } private void SendData() { Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); byte[] fileName = Encoding.UTF8.GetBytes(m_fName); byte[] fileData = File.ReadAllBytes(textBox1.Text); byte[] fileNameLen = BitConverter.GetBytes(fileName.Length); byte[] fileType = BitConverter.GetBytes((int)DataPacketType.IMAGE); // IMAGE(4 byte) + 파일이름(4 byte) + 파일이름길이(4 byte) + 데이타 길이 m_clientData = new byte[fileType.Length + 4 + fileName.Length + fileData.Length]; fileType.CopyTo(m_clientData, 0); fileNameLen.CopyTo(m_clientData, 4); fileName.CopyTo(m_clientData, 8); fileData.CopyTo(m_clientData, 8 + fileName.Length); clientSocket.Connect(IPAddress.Parse("192.168.0.11"), 9050); clientSocket.Send(m_clientData); clientSocket.Close(); } private void btnSendText_Click(object sender, EventArgs e) { Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); byte[] textData = Encoding.UTF8.GetBytes(textBox2.Text); byte[] fileType = BitConverter.GetBytes((int)DataPacketType.TEXT); // TEXT(4 byte) + 데이타 길이 m_clientData = new byte[fileType.Length + textData.Length]; fileType.CopyTo(m_clientData, 0); textData.CopyTo(m_clientData, 4); clientSocket.Connect(IPAddress.Parse("192.168.0.11"), 9050); clientSocket.Send(m_clientData); clientSocket.Close(); } }
'C# with TCP/IP' 카테고리의 다른 글
[Program C#] Check all client connection. (0) | 2015.05.20 |
---|---|
[Program C#]이미지 파일과 텍스트 전송 - 2 (1) | 2015.04.02 |
[Program C#] SslStream 을 이용한 통신 방법 (1) | 2015.03.20 |
[Program C#] 서버-클라이언트 채팅 통신 (0) | 2015.03.17 |
[Program C#] 서버-클라이언트 1:N 통신 (1) | 2015.03.14 |