DS 's RoOm
김도선님의 블로그입니다
2012년 12월 17일 월요일
Socket(Tcp) 동기 Server
c# Socket(Tcp)를 이용한 싱글 서버를 구현해봤습니다. 수정할 부분이 많습니다.-_-
public class LocalSocket { private Socket m_hSock; // host private Socket m_cSock; // client private IPEndPoint m_hEp; private byte[] m_receiveByte; private BackgroundWorker m_bwReceiver; public static LocalSocket sockTrade; private readonly int MAXSIZE = 1024; private bool m_CLOSE = false; public static LocalSocket Instance() { if (sockTrade == null) { sockTrade = new LocalSocket(); } return sockTrade; } private LocalSocket() { this.m_bwReceiver = new BackgroundWorker(); this.m_bwReceiver.WorkerSupportsCancellation = true; this.m_bwReceiver.DoWork += new DoWorkEventHandler(bw_Receiver); this.m_bwReceiver.RunWorkerCompleted += new RunWorkerCompletedEventHandler(DisconnectFormClient); try { this.m_hSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); this.m_hEp = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9999); this.m_cSock = null; this.m_receiveByte = new byte[MAXSIZE]; this.m_hSock.Bind(m_hEp); // bind } catch (SocketException se) { // } } ///
/// 1. 서버(자신)의 포트를 열고 /// 2. 클라이언트의 연결시도 대기 -> 연결완료 /// 3. BackgroundWorker로 Receive(메소드 호출 ) ///
public void Open() { this.m_hSock.Listen(1); // Console.WriteLine("클라이언트 연결을 대기중입니다....."); m_cSock = m_hSock.Accept(); // client instance 생성 if (m_cSock.IsBound) // 재차 확인 { // Console.WriteLine("클라이언트 연결 완료....."); IPEndPoint ep = (IPEndPoint)m_cSock.RemoteEndPoint; if (this.ClientIsConnected != null) this.ClientIsConnected(this, new LocalSocketEvent(true, ep)); // Background 실행여부 if (!m_bwReceiver.IsBusy) this.m_bwReceiver.RunWorkerAsync(); // Receive Backgorund 호출 } else { // Disconnect Event Fire if (this.ClientFireDisConnected != null) this.ClientFireDisConnected(this, new LocalSocketEvent(true)); } } // close Open public void Send(string str) { try { if (m_cSock.Connected) { byte[] sendByte = new UTF8Encoding().GetBytes(str); m_cSock.Send(sendByte, sendByte.Length, SocketFlags.None); } } catch (SocketException se) { // Sending Event Fire if (this.SendingFireError != null) this.SendingFireError(this, new LocalSocketEvent(true)); return; } } public void Dispose() { try { if (this.m_hSock != null) { this.m_CLOSE = true; this.m_bwReceiver.CancelAsync(); if (this.m_cSock != null && this.m_cSock.Connected) { this.m_cSock.Close(); } // this.m_hSock.Shutdown(SocketShutdown.Both); this.m_hSock.Close(); } } catch (SocketException e) { Console.WriteLine("LocalSocket Exception {0}, {1}", e.Message, e.SocketErrorCode); } Console.WriteLine(" localSocket CLOSE"); } ///
/// 백그라운드로 데이터 계속 받음 /// 중간에 연결 끊김시 재시작 ///
///
///
private void bw_Receiver(object sender, DoWorkEventArgs e) { string t_Receive = string.Empty; while (this.m_cSock.Connected) { try { // Console.WriteLine("클라이언트로부터 응답을 받을때까지 대기합니다..."); Array.Clear(this.m_receiveByte, 0, MAXSIZE); int size = 0; if ((size = m_cSock.Receive(this.m_receiveByte)) > 0) // { // Console.WriteLine("받은 데이터 charact 수: {0}", size); t_Receive = new UTF8Encoding().GetString(m_receiveByte); // Receive Event Fire if (this.Received != null) this.Received(this, new LocalSocketEvent(t_Receive.Trim('\0'))); } } catch (SocketException se) { if (se.SocketErrorCode == SocketError.ConnectionReset) // Client 접속이 끊김 { // Console.WriteLine("{0} Error Code: {1}, Receiver BW()", se.Message, se.ErrorCode); e.Cancel = true; // Disconnecte Event Fire if (this.ClientFireDisConnected != null) this.ClientFireDisConnected(this, new LocalSocketEvent(true)); this.m_bwReceiver.CancelAsync(); break; } } } // close while } // close bw_Receiver(objet sender, DoWorkEventArgs e); private void DisconnectFormClient(object sender, RunWorkerCompletedEventArgs e) { if (e.Cancelled) { if(!this.m_CLOSE) this.Open(); // 서버(본인) 다시 개방하고 클라이언트로 부터접속대기 } } public class LocalSocketEvent : EventArgs { public string Message; public bool ClientIsConnected; // 연결 public bool ClientIsDisConnected; // 끊김 public IPEndPoint ClientEP; public LocalSocketEvent(string str) { this.Message = str; } public LocalSocketEvent(bool isConnected, IPEndPoint ep) { this.ClientIsConnected = isConnected; this.ClientEP = ep; } public LocalSocketEvent(bool isDisconnect) { this.ClientIsDisConnected = isDisconnect; } } // close SockTrade // 받았을때 BW_RECEIVER 발생 public delegate void ReceiverHandler(object sender, LocalSocketEvent e); public event ReceiverHandler Received; // 클라이언트 접속시발생 public delegate void ClientIsConnectHandler(object sender, LocalSocketEvent e); public event ClientIsConnectHandler ClientIsConnected; // 클라이언트로 데이터 전송시 발생 public delegate void SendErrorHandler(object sender, LocalSocketEvent e); public event SendErrorHandler SendingFireError; public delegate void ClientFireDisConnect(object sender, LocalSocketEvent e); public event ClientFireDisConnect ClientFireDisConnected; } }
댓글 없음:
댓글 쓰기
최근 게시물
이전 게시물
홈
피드 구독하기:
댓글 (Atom)
댓글 없음:
댓글 쓰기