void RemoveThread(int id) { if (_clientThreads.ContainsKey(id)) { try{ _clients[id].Client.Blocking = false; _clients[id].Client.Disconnect(false); _clients[id].Client.Close(1000); }catch {} try { _clients.Remove(id); Thread t = _clientThreads[id]; try { _clientThreads[id].Abort(); _clientThreads[id].Join(1000); } catch { } _clientThreads.Remove(id); } catch (Exception e) { Win32APIs.SendMsgData("TcpClientBase.RemoveThread:" + e.Message, "LogWindow"); } } }
void whenConnectionFailed(int id) { Win32APIs.SendMsgData("tryConnection:연결시도가 실패하였음.", "LogWindow"); if (_isPermarnentConnecting) { Win32APIs.SendMsgData("tryConnection:계속 접속모드: 재접속 호출", "LogWindow"); if (id == _threadId) { ConnectionEvent(ConnType.Connecting); } if (_isDisposing == false) { Thread.Sleep(1000); if (_isDisposing == false) { StartConnection(_connectionTimeout, _runRecvThreadWhenConnected); } } } else { Win32APIs.SendMsgData("tryConnection:연결시도 마침.", "LogWindow"); //_isConnecting = false; if (id == _threadId) { ConnectionEvent(ConnType.Disconnected); } } Win32APIs.SendMsgData("tryConnection:기존 thread 삭제", "LogWindow"); RemoveThread(id); }
void whenConnectionFailed(int id) { Win32APIs.SendMsgData("TcpClientBase.tryConnection: start connection fail process.", "LogWindow"); if (_isPermarnentConnecting) { Win32APIs.SendMsgData("TcpClientBase.tryConnection: permanent connection mode: trying reconnect", "LogWindow"); if (id == _threadId) { ConnectionEvent(ConnType.Connecting); } if (_isDisposing == false) { Thread.Sleep(1000); if (_isDisposing == false) { StartConnection(_connectionTimeout, _runRecvThreadWhenConnected); } } } else { Win32APIs.SendMsgData("TcpClientBase.tryConnection:finish trying connection.", "LogWindow"); //_isConnecting = false; if (id == _threadId) { ConnectionEvent(ConnType.Disconnected); } } Win32APIs.SendMsgData("TcpClientBase.tryConnection:removing current thread[" + id + "]", "LogWindow"); RemoveThread(id); Win32APIs.SendMsgData("TcpClientBase.tryConnection: current thread[" + id + "] removed", "LogWindow"); }
public void releaseRecvThread() { if (_recvThread == null) { return; } if (_recvThread != null) { _isEndConnection = true; //thread 종료조건 설정 후 while (_isRecvThreadRunning) { writeLog("waiting recv thread stopping..."); if (_server != null && _server.Client != null) { if (_server.Client.Blocking) { _server.Client.Blocking = false; } try{ _server.Close(); }catch { Win32APIs.SendMsgData("TcpClientBase:Thread해제시 소켓클로즈 안됨.", "LogWindow"); } _server.Client = null; _recvThread.Abort(); _recvThread = null; } Thread.Sleep(100); } } }
/// <summary> /// 모든 실행중인 thread와 연결시도를 끝낸다. /// </summary> public override void Close() { //_connectionTimer.Stop(); _isDisposing = true; _isPermarnentConnecting = false; Win32APIs.SendMsgData("TcpClientBase.Close: closing connection...", "LogWindow"); //releaseThreads(); Disconnect(); }
/// <summary> /// 타이머가 계속 돌면서 연결중인지 아닌지를 검사함.. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void _connectionTimer_Elapsed(object sender, Timers.ElapsedEventArgs e) { if (_serverIp.Length == 0) { return; //초기상태 } try { if (_server.Client.Connected) //연결되었으면 { ConnectionEvent(ConnType.Connected); //연결이 되어있는 상태라면 이 명령은 효과없음.. } else //연결이 아직 안되었는데,, { Win32APIs.SendMsgData("접속 타이머: 연결 아직 안됨.", "LogWindow"); Win32APIs.SendMsgData("접속 타이머: 접속 시도중.", "LogWindow"); if (_isPermarnentConnecting) //계속 체크중인 것 { ConnectionEvent(ConnType.Connecting); } else //timeout에 걸린 것 { _server.Client.Close(1000); ///_server.Close(); //연결 중이라고 해도 끊음.. ConnectionEvent(ConnType.Disconnected); } } } catch (Exception ex) { //소켓이 손상되었을 때 _connectionTimer.Stop(); Win32APIs.SendMsgData("접속 타이머: 소켓 손상의심: " + ex.Message, "LogWindow"); if (_isPermarnentConnecting) //계속 체크중인 것 { ConnectionEvent(ConnType.Disconnected); Win32APIs.SendMsgData("접속 타이머: 계속 접속모드 - 재접속", "LogWindow"); if (_isDisposing == false) { StartConnection(0, _runRecvThreadWhenConnected); //소켓을 다시 만들어야한다. } } else //다시 만들 필요가 없다. 기다리지 않는 모드이므로.. { Win32APIs.SendMsgData("접속 타이머: 단일 접속모드 - 접속끊음.", "LogWindow"); ConnectionEvent(ConnType.Disconnected); } } }
// Socket _runningSocket = null; private void serverLoop() { while (!_isEndServer) { int id = -1; Console.WriteLine("server ready..."); try { TcpClient client = _listener.AcceptTcpClient(); if (_isEndServer) { break; } id = getBlankClient(); if (id >= 0) { _client[id] = client; } else { Win32APIs.SendMsgData("TcpServerBase.serverLoop: Server Listener: 한계크기" + _maxClientNum + "보다 큰 접속 시도. 끊음..", "LogWindow"); client.Close(); //그냥 끊어버림.. Thread.Sleep(1000); //1초 뒤에 다시 받음.. continue; } _isEndConnection[id] = false; _queue[id].Clear(); //초기화 ConnectionEvent(ConnType.Connected, id); } catch { this.Disconnect(); OnConnectionFailed(); break; } if (_isRunRecvThreadWhenConnected) { makeRecvThread(id); } } Console.WriteLine("exit from while in Server..."); _listener = null; }
private void tryConnection() { int id = _threadId; //현재 id를 이thread가 끝나는 순간까지 가지고 있는다. TcpClient conn = new TcpClient(); _clients[id] = conn; _queue.Clear();//이전 것은 의미가 없으므로 다시 큐를 비워줌.. Win32APIs.SendMsgData("TcpClientBase.tryConnection: new socket created", "LogWindow"); Win32APIs.SendMsgData("TcpClientBase.tryConnection: trying connection...", "LogWindow"); try { conn.Connect(_serverIp, _serverPort); } catch (Exception e) { Win32APIs.SendMsgData("TcpClientBase.tryConnection: failed to connect" + e.Message, "LogWindow"); whenConnectionFailed(id); return; } Win32APIs.SendMsgData("TcpClientBase.tryConnection: connection completed", "LogWindow"); if (conn != null && conn.Client != null && conn.Connected == true) { Win32APIs.SendMsgData("TcpClientBase.tryConnection: connected", "LogWindow"); ConnectionEvent(ConnType.Connected); Win32APIs.SendMsgData("TcpClientBase.tryConnection: after connection process done(" + _serverIp + ":" + _serverPort + ")", "LogWindow"); //_isConnecting = false; if (_runRecvThreadWhenConnected) { recvLoop(); Win32APIs.SendMsgData("TcpClientBase.tryConnection: recv loop has finished because of some fault...", "LogWindow"); //_checkConnectionThread.Abort(); //연결이 끊어지거나 문제가있어서 끝난 것. 후속처리.. if (_isDisposing == false) { whenConnectionFailed(id); Win32APIs.SendMsgData("TcpClientBase.tryConnection: after recv loop finish process done...", "LogWindow"); } //끝나면 thread를 삭제해야 함..v } } else { Win32APIs.SendMsgData("TcpClientBase.tryConnection: connection failed", "LogWindow"); whenConnectionFailed(id); Win32APIs.SendMsgData("TcpClientBase.tryConnection: after connection fail process done...", "LogWindow"); return; } #region old /* * try * { * while (_isConnecting) * { * if (_nowConn != null && _nowConn.Client.Connected) * { * * //_checkConnectionThread.Abort(); * break;// return; * } * else * { * if (_isDisposing == false) * { * try * { * Win32APIs.SendMsgData("tryConnection: 접속 시도", "LogWindow"); * _nowConn.Connect(_serverIp, _serverPort); * Win32APIs.SendMsgData("tryConnection: 접속 시도 끝", "LogWindow"); * * if (_nowConn != null && _nowConn.Client != null && _nowConn.Connected == true) * { * Win32APIs.SendMsgData("tryConnection: 연결됨1", "LogWindow"); * ConnectionEvent(ConnType.Connected); * Win32APIs.SendMsgData("tryConnection: 연결됨2", "LogWindow"); * _isConnecting = false; * runRecvThread(); * //_checkConnectionThread.Abort(); * } * else * { * Win32APIs.SendMsgData("tryConnection:연결된 후 뭔가 잘못되었다.", "LogWindow"); * if (_isPermarnentConnecting) * { * Win32APIs.SendMsgData("tryConnection:계속 접속모드: 재접속 호출", "LogWindow"); * _connectionState = ConnType.Disconnected; * _isConnecting = false; * _connectionTimer.Start(); * //if (_isDisposing == false) StartConnection(_connectionTimeout, _runRecvThreadWhenConnected); * * break;// return; * } * else * { * Win32APIs.SendMsgData("tryConnection:연결시도 마침.", "LogWindow"); * _isConnecting = false; * ConnectionEvent(ConnType.Disconnected); * //_checkConnectionThread.Abort(); * } * } * * } * catch (Exception e) * { * Win32APIs.SendMsgData("tryConnection:CONNECTION 실패 1:" + e.Message + "재접속 시도", "LogWindow"); * Win32APIs.SendMsgData("tryConnection:재접속시도", "LogWindow"); * Thread.Sleep(1000); * if (_isPermarnentConnecting) * { * Win32APIs.SendMsgData("tryConnection:계속 접속모드: 재접속 호출", "LogWindow"); * _connectionState = ConnType.Disconnected; * * //_isConnecting = false; * //_connectionTimer.Start(); * if (_isDisposing == false) StartConnection(_connectionTimeout, _runRecvThreadWhenConnected); * break; * } * else * { * _isConnecting = false; * Win32APIs.SendMsgData("tryConnection:연결시도 마침.", "LogWindow"); * ConnectionEvent(ConnType.Disconnected); * break;//return; * } * // _checkConnectionThread.Abort(); * * } * } * else * { * //_checkConnectionThread.Abort(); * break;// return; * } * } * } * } * catch { } * _isConnecting = false; */ #endregion }
/* * public void releaseRecvThread() * { * if (_recvThread == null) * { * return; * } * * if (_recvThread != null) * { * * _isEndConnection = true; //thread 종료조건 설정 후 * while (_isRecvThreadRunning) * { * writeLog("waiting recv thread stopping..."); * if(_nowConn!=null && _nowConn.Client!=null){ * if(_nowConn.Client.Blocking) _nowConn.Client.Blocking = false; * try{ * _nowConn.Close(); * }catch{ * Win32APIs.SendMsgData("TcpClientBase:Thread해제시 소켓클로즈 안됨.", "LogWindow"); * * } * _nowConn.Client = null; * * } * Thread.Sleep(100); * } * _recvThread.Abort(); * _recvThread = null; * } * } */ /// <summary> /// Thread를 끝내지 않고 connection만 끝낸다. /// 이 명령은 ConnectionEvent를 발생시키지 않지만 PermanantConnection모드에서는 /// 다시 접속을 시도한다. /// </summary> public override void Disconnect(Func <int> funcRunningBeforeCloseSocket = null) { if (funcRunningBeforeCloseSocket != null) { funcRunningBeforeCloseSocket.Invoke(); } releaseThreads(); releaseResources(); ConnectionEvent(ConnType.Disconnected); _connectionState = ConnType.Disconnected; Win32APIs.SendMsgData("TcpClientBase.Disconnect: disconnected.", "LogWindow"); #region old /* * * if (_nowConn != null && _nowConn.Client != null) * { * if (_nowConn.Client.Blocking) _nowConn.Client.Blocking = false; * Win32APIs.SendMsgData("Blocking 해제...", "LogWindow"); * } * * * if (_nowConn!=null && _nowConn.Client != null) * { * Byte[] buff = new Byte[1]; * SocketError error = SocketError.NoData; * _nowConn.SendTimeout = 1000; * if (funcRunningBeforeCloseSocket != null) funcRunningBeforeCloseSocket.Invoke(); * * * //int recv = _server.Client.Send(buff, 0, 1, SocketFlags.None, out error); * //Win32APIs.SendMsgData("1byte 보낸 것 성공?"+recv+"\r\n", "LogWindow"); * //if (error != SocketError.Success) * //{ * // Win32APIs.SendMsgData("소켓손상...", "LogWindow"); * //이미 소켓이 손상된 경우.. * // _server = null; * //} * //else {//끝내기 전에 사용자가 원하는 작업 한 가지를 하고 끝낼 수 있다. * * try * { * Win32APIs.SendMsgData("disconnect시도", "LogWindow"); * try * { * _nowConn.Client.Blocking = false; * _nowConn.Client.Disconnect(false); * Win32APIs.SendMsgData("disconnect완료", "LogWindow"); * } * catch(Exception ex) * { * Win32APIs.SendMsgData("disconnect시 에러:"+ex.Message, "LogWindow"); * } * Win32APIs.SendMsgData("close시도", "LogWindow"); * * _nowConn.Client.Close(1000); * Win32APIs.SendMsgData("close완료", "LogWindow"); * } * catch(Exception e) { * Win32APIs.SendMsgData("close시 에러..\r\n"+e.Message, "LogWindow"); * } * * //} * } * //미리 삭제된 개체였을 가능성.. * _nowConn = null; * _connectionState = ConnType.Disconnected; * //ConnectionEvent(ConnType.Disconnected); */ #endregion }
private void tryConnection() { int id = _threadId; //현재 id를 이thread가 끝나는 순간까지 가지고 있는다. Win32APIs.SendMsgData("StartConnection: 소켓 새로 생성", "LogWindow"); TcpClient conn = new TcpClient(); _clients.Add(id, conn); _queue.Clear();//이전 것은 의미가 없으므로 다시 큐를 비워줌.. Win32APIs.SendMsgData("StartConnection: 소켓 새로 생성 완료", "LogWindow"); Win32APIs.SendMsgData("tryConnection: 접속 시도", "LogWindow"); try { conn.Connect(_serverIp, _serverPort); } catch (Exception e) { Win32APIs.SendMsgData("tryConnection: 접속 실패." + e.Message, "LogWindow"); whenConnectionFailed(id); return; } Win32APIs.SendMsgData("tryConnection: 접속 시도 끝", "LogWindow"); if (conn != null && conn.Client != null && conn.Connected == true) { Win32APIs.SendMsgData("tryConnection: 연결됨1", "LogWindow"); ConnectionEvent(ConnType.Connected); Win32APIs.SendMsgData("tryConnection: 연결됨2", "LogWindow"); //_isConnecting = false; if (_runRecvThreadWhenConnected) { recvLoop(); //_checkConnectionThread.Abort(); //연결이 끊어지거나 문제가있어서 끝난 것. 후속처리.. if (_isDisposing == false) { whenConnectionFailed(id); } //끝나면 thread를 삭제해야 함..v } } else { whenConnectionFailed(id); return; } #region old /* * try * { * while (_isConnecting) * { * if (_nowConn != null && _nowConn.Client.Connected) * { * * //_checkConnectionThread.Abort(); * break;// return; * } * else * { * if (_isDisposing == false) * { * try * { * Win32APIs.SendMsgData("tryConnection: 접속 시도", "LogWindow"); * _nowConn.Connect(_serverIp, _serverPort); * Win32APIs.SendMsgData("tryConnection: 접속 시도 끝", "LogWindow"); * * if (_nowConn != null && _nowConn.Client != null && _nowConn.Connected == true) * { * Win32APIs.SendMsgData("tryConnection: 연결됨1", "LogWindow"); * ConnectionEvent(ConnType.Connected); * Win32APIs.SendMsgData("tryConnection: 연결됨2", "LogWindow"); * _isConnecting = false; * runRecvThread(); * //_checkConnectionThread.Abort(); * } * else * { * Win32APIs.SendMsgData("tryConnection:연결된 후 뭔가 잘못되었다.", "LogWindow"); * if (_isPermarnentConnecting) * { * Win32APIs.SendMsgData("tryConnection:계속 접속모드: 재접속 호출", "LogWindow"); * _connectionState = ConnType.Disconnected; * _isConnecting = false; * _connectionTimer.Start(); * //if (_isDisposing == false) StartConnection(_connectionTimeout, _runRecvThreadWhenConnected); * * break;// return; * } * else * { * Win32APIs.SendMsgData("tryConnection:연결시도 마침.", "LogWindow"); * _isConnecting = false; * ConnectionEvent(ConnType.Disconnected); * //_checkConnectionThread.Abort(); * } * } * * } * catch (Exception e) * { * Win32APIs.SendMsgData("tryConnection:CONNECTION 실패 1:" + e.Message + "재접속 시도", "LogWindow"); * Win32APIs.SendMsgData("tryConnection:재접속시도", "LogWindow"); * Thread.Sleep(1000); * if (_isPermarnentConnecting) * { * Win32APIs.SendMsgData("tryConnection:계속 접속모드: 재접속 호출", "LogWindow"); * _connectionState = ConnType.Disconnected; * * //_isConnecting = false; * //_connectionTimer.Start(); * if (_isDisposing == false) StartConnection(_connectionTimeout, _runRecvThreadWhenConnected); * break; * } * else * { * _isConnecting = false; * Win32APIs.SendMsgData("tryConnection:연결시도 마침.", "LogWindow"); * ConnectionEvent(ConnType.Disconnected); * break;//return; * } * // _checkConnectionThread.Abort(); * * } * } * else * { * //_checkConnectionThread.Abort(); * break;// return; * } * } * } * } * catch { } * _isConnecting = false; */ #endregion }
private void tryConnection() { if (_server != null && _server.Client.Connected) { //_checkConnectionThread.Abort(); return; } else { if (_isDisposing == false) { try { Win32APIs.SendMsgData("tryConnection: 접속 시도", "LogWindow"); _server.Connect(_serverIp, _serverPort); Win32APIs.SendMsgData("tryConnection: 접속 시도 끝", "LogWindow"); if (_server != null && _server.Client != null && _server.Connected == true) { Win32APIs.SendMsgData("tryConnection: 연결됨1", "LogWindow"); ConnectionEvent(ConnType.Connected); Win32APIs.SendMsgData("tryConnection: 연결됨2", "LogWindow"); _isConnecting = false; //_checkConnectionThread.Abort(); } else { Win32APIs.SendMsgData("tryConnection:연결된 후 뭔가 잘못되었다.", "LogWindow"); if (_isPermarnentConnecting) { Win32APIs.SendMsgData("tryConnection:계속 접속모드: 재접속 호출", "LogWindow"); _connectionState = ConnType.Disconnected; _isConnecting = false; _connectionTimer.Start(); //if (_isDisposing == false) StartConnection(_connectionTimeout, _runRecvThreadWhenConnected); return; } else { Win32APIs.SendMsgData("tryConnection:연결시도 마침.", "LogWindow"); _isConnecting = false; ConnectionEvent(ConnType.Disconnected); //_checkConnectionThread.Abort(); } } } catch (Exception e) { Win32APIs.SendMsgData("tryConnection:CONNECTION 실패 1:" + e.Message + "재접속 시도", "LogWindow"); Win32APIs.SendMsgData("tryConnection:재접속시도", "LogWindow"); if (_isPermarnentConnecting) { Win32APIs.SendMsgData("tryConnection:계속 접속모드: 재접속 호출", "LogWindow"); _connectionState = ConnType.Disconnected; _isConnecting = false; _connectionTimer.Start(); //if (_isDisposing == false) StartConnection(_connectionTimeout, _runRecvThreadWhenConnected); } else { _isConnecting = false; Win32APIs.SendMsgData("tryConnection:연결시도 마침.", "LogWindow"); ConnectionEvent(ConnType.Disconnected); } // _checkConnectionThread.Abort(); return; } } else { //_checkConnectionThread.Abort(); return; } } }
/// <summary> /// 연결시도를 시작한다. 무한대기를 위해서는 connectionTimeout을 0으로 하면 된다. /// </summary> /// <param name="connectionTimeoutWithMs">연결시도 timeout 시간. ms단위. 0으로 하면 무한히 연결시도를한다.</param> /// <param name="runRecvThreadWhenConnected">true일 경우 receive thread를 연결되자마자 자동으로 시작함.</param> void StartConnection(int connectionTimeoutWithMs = 2000, bool runRecvThreadWhenConnected = false) { if (_isConnecting) { return; } _isConnecting = true; if (connectionTimeoutWithMs <= 0) { _isPermarnentConnecting = true; } else { _isPermarnentConnecting = false; } if (_connectionState != ConnType.Disconnected) //현재 연결진행중이면 그냥 나간다. { Win32APIs.SendMsgData("StartConnection: 이미 연결되었거나 연결중 - 무시", "LogWindow"); return; } else { if (_connectionTimer.Enabled == true) { _connectionTimer.Stop(); //timeout을 위하여 } _connectionTimer.Interval = (_isPermarnentConnecting) ? 1000 : connectionTimeoutWithMs; //무한대기는 1000ms마다 체크한다. ConnectionEvent(ConnType.Connecting); _isDisposing = false; _queue.Clear(); _runRecvThreadWhenConnected = runRecvThreadWhenConnected; if (_server != null && _server.Client != null) { try { Win32APIs.SendMsgData("StartConnection: 기존 연결 Disconnect", "LogWindow"); _server.Client.Disconnect(false); Win32APIs.SendMsgData("StartConnection: 이전 연결 Disconnect성공:", "LogWindow"); } catch (Exception e) { Win32APIs.SendMsgData("StartConnection: 이전 소켓 disconnect시 실패:" + e.Message, "LogWindow"); } try { Win32APIs.SendMsgData("StartConnection: 기존 소켓 Close", "LogWindow"); _server.Client.Close(1000); Win32APIs.SendMsgData("StartConnection: 이전 소켓 Close성공:", "LogWindow"); } catch (Exception e) { Win32APIs.SendMsgData("StartConnection: 이전 소켓 Close시 실패:" + e.Message, "LogWindow"); } } _server = null; if (_checkConnectionThread != null) //기존에 연결시도중인 연결이 있다면 삭제하는 루틴.. { Win32APIs.SendMsgData("StartConnection: 기존 Thread 삭제 시도", "LogWindow"); if (_checkConnectionThread.ThreadState != ThreadState.Aborted && _checkConnectionThread.ThreadState != ThreadState.AbortRequested && _checkConnectionThread.ThreadState != ThreadState.Stopped) { Win32APIs.SendMsgData("StartConnection: 기존 Thread 삭제 중- 현재상태:" + _checkConnectionThread.ThreadState.ToString(), "LogWindow"); _checkConnectionThread.Abort(); _checkConnectionThread = null; Win32APIs.SendMsgData("StartConnection: 기존 Thread 삭제 완료", "LogWindow"); } else { Win32APIs.SendMsgData("StartConnection: 기존 Thread 삭제 필요없음.", "LogWindow"); } } Win32APIs.SendMsgData("StartConnection: 소켓 새로 생성", "LogWindow"); _server = new TcpClient(); Win32APIs.SendMsgData("StartConnection: 소켓 새로 생성 완료", "LogWindow"); _checkConnectionThread = new Thread(new ThreadStart(tryConnection)); _checkConnectionThread.Start(); _connectionTimer.Start(); } }
/// <summary> /// Thread를 끝내지 않고 connection만 끝낸다. /// 이 명령은 ConnectionEvent를 발생시키지 않지만 PermanantConnection모드에서는 /// 다시 접속을 시도한다. /// </summary> public void Disconnect(Func <int> funcRunningBeforeCloseSocket = null) { releaseResources(); if (_server != null && _server.Client != null) { if (_server.Client.Blocking) { _server.Client.Blocking = false; } Win32APIs.SendMsgData("Blocking 해제...", "LogWindow"); } if (_server != null && _server.Client != null) { Byte[] buff = new Byte[1]; SocketError error = SocketError.NoData; _server.SendTimeout = 1000; if (funcRunningBeforeCloseSocket != null) { funcRunningBeforeCloseSocket.Invoke(); } //int recv = _server.Client.Send(buff, 0, 1, SocketFlags.None, out error); //Win32APIs.SendMsgData("1byte 보낸 것 성공?"+recv+"\r\n", "LogWindow"); //if (error != SocketError.Success) //{ // Win32APIs.SendMsgData("소켓손상...", "LogWindow"); //이미 소켓이 손상된 경우.. // _server = null; //} //else {//끝내기 전에 사용자가 원하는 작업 한 가지를 하고 끝낼 수 있다. try { Win32APIs.SendMsgData("disconnect시도", "LogWindow"); try { _server.Client.Disconnect(false); Win32APIs.SendMsgData("disconnect완료", "LogWindow"); } catch (Exception ex) { Win32APIs.SendMsgData("disconnect시 에러:" + ex.Message, "LogWindow"); } Win32APIs.SendMsgData("close시도", "LogWindow"); _server.Client.Close(1000); Win32APIs.SendMsgData("close완료", "LogWindow"); } catch (Exception e) { Win32APIs.SendMsgData("close시 에러..\r\n" + e.Message, "LogWindow"); } //} } //미리 삭제된 개체였을 가능성.. _server = null; _connectionState = ConnType.Disconnected; //ConnectionEvent(ConnType.Disconnected); }