//서버 소켓을 열어서 준비한다. private void openServerSocket() { try { //Port 설정 후 Listen 대기 ipEndPointForServer = new IPEndPoint(IPAddress.Any, portNumber); serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); serverSocket.Bind(ipEndPointForServer); serverSocket.Listen(20);//연결 수 지정 startMessengerTime = DateTime.Now.ToString("yyyy.MM.dd-HH:mm:ss"); //서버 준비가 완료되었다는 메세지 표시 MessageInfo messageInfo = new MessageInfo("message", "Server", LanguageResource.language_res.strMessageToNotifyServerIsOpened, getCurrentTime(), 0 + ""); string messageInXML = XMLHandlerForMessage.convertStringToXml(messageInfo); putMessageOnMessageBoard(messageInXML); } catch (SocketException ex) { throw new PortNumberAlreadyUsedException(); } catch (Exception ex) { MessageBox.Show("openServerSocket 에서 에러 발생\n" + ex.ToString()); } }
private void createThreadForEmailAndDatabase() { string filePath = XMLHandlerForMessage.createXmlFileFromString(listOfMessage); EmailHandler.sendEmail(filePath); new DatabaseHandler().insertMessengerRecordIntoDB(filePath, startMessengerTime, DateTime.Now.ToString("yyyy.MM.dd-HH:mm:ss"), portNumber); //DB 기능은 프로젝트 속성에서 Target Platform이 32bit 운영체제로 되는걸 전제로 실행된다. //DB가 준비되어 있지 않다면, 김범준 컴퓨터에서만 실행 가능. }
//서버에게 XML 메세지를 패킷으로 송신 private void sendMessageToServer(string messageInXML) { try { Byte[] messageData = Encoding.Default.GetBytes(messageInXML); clientSocket.Send(messageData); } catch (SocketException e) { MessageInfo messageInfo = new MessageInfo("message", "Server", LanguageResource.language_res.strMessageToNotifyClientIsDisconnectedFromServer, getCurrentTime(), "0"); messageInXML = XMLHandlerForMessage.convertStringToXml(messageInfo); putMessageOnMessageBoard(messageInXML); } }
private void acceptClientSocket() { try { int userNumber = 1; while (serverAlive) { //클라이언트가 들어오면, 접속을 받아들인다. Socket clientSocket = serverSocket.Accept(); //먼저 클라이언트로부터 userName을 받기 위해 메세지를 한번은 기다린다 Byte[] messageData = new Byte[1024]; clientSocket.Receive(messageData); string clientUserName = Encoding.Default.GetString(messageData); //그리고 클라이언트에게 배정한 userNumber를 전송한다 messageData = new Byte[1024]; messageData = Encoding.Default.GetBytes("" + userNumber); clientSocket.Send(messageData); //클라이언트의 정보를 서버에 저장 ClientInfo client = new ClientInfo(); client.ClientSocket = clientSocket; client.ClientSocketAlive = true; client.UserName = clientUserName; client.UserNumber = userNumber; listOfClient.AddLast(client); //리스트에 클라이언트 정보를 저장 userNumber++; //클라이언트 한명이 입장했다는 메세지를 존재하는 모든 클라이언트에게 전송 string message = (client.userName + " [" + client.userNumber + "] " + LanguageResource.language_res.strMessageToNotifyClientJoinedServer); MessageInfo messageInfo = new MessageInfo("message", "Server", message, getCurrentTime(), 0 + ""); string messageInXML = XMLHandlerForMessage.convertStringToXml(messageInfo); sendMessageToConnectedClients(messageInXML); //클라이언트로부터 메세지를 받기위한 스레드를 각각 생성 createThreadToReceiveMessageFromClient(client); } } catch (SocketException ex) { //클라이언트가 퇴장할 때마다 한번씩은 에러가 발생되기에 넘긴다. }catch (Exception ex) { MessageBox.Show("acceptClientSocket 에서 에러 발생\n" + ex.ToString()); } }
//클라이언트 서버에서 내보내기 private void removeClientFromServer(ClientInfo client) { try { client.ClientSocketAlive = false; //내보내려는 클라이언트의 활성상태 false로 변경 client.ClientSocket.Close(); //내보내려는 클라이언트의 소켓 닫기 string message = client.userName + " [" + client.userNumber + "] " + LanguageResource.language_res.strMessageToNotifyClientLeftServer; MessageInfo messageInfo = new MessageInfo("message", "Server", message, getCurrentTime(), 0 + ""); string messageInXML = XMLHandlerForMessage.convertStringToXml(messageInfo); listOfClient.Remove(client); //내보내려는 클라이언트의 정보 삭제 sendMessageToConnectedClients(messageInXML); } catch (Exception ex) { MessageBox.Show("removeClientFromServer 에서 에러 발생\n" + ex.ToString()); } }
//서버로부터 XML 메세지를 패킷으로 수신 private void receiveMessageFromServer() { try { while (clientAlive) { Byte[] messageData = new Byte[1024]; clientSocket.Receive(messageData); String messageInXML = Encoding.Default.GetString(messageData); putMessageOnMessageBoard(messageInXML); } } catch (Exception ex) { MessageInfo messageInfo = new MessageInfo("message", "Server", LanguageResource.language_res.strMessageToNotifyClientIsDisconnectedFromServer, getCurrentTime(), "0"); string messageInXML = XMLHandlerForMessage.convertStringToXml(messageInfo); putMessageOnMessageBoard(messageInXML); //MessageBox.Show(LanguageResource.language_res.strMessageToNotifyClientIsDisconnectedFromServer, userName); } }
//전송된 메세지를 서버 창에 띄어주기 private void putMessageOnMessageBoard(string messageInXML) { Dispatcher.Invoke(DispatcherPriority.Normal, new Action(delegate {//다른 스레드에서 UI를 컨트롤 하기 위한 Dispatcher.Invoke(); MessageInfo messageInfo = XMLHandlerForMessage.readXmlToGetMessage(messageInXML); TextBox textBoxSender = new TextBox(); textBoxSender.IsReadOnly = true; textBoxSender.Background = new SolidColorBrush(Colors.Transparent); textBoxSender.FontWeight = FontWeights.ExtraBold; textBoxSender.BorderThickness = new Thickness(0); textBoxSender.FontSize = 18; textBoxSender.Text = messageInfo.sender + " [" + messageInfo.userNumber + "] - " + messageInfo.time; TextBox textBoxMessage = new TextBox(); textBoxMessage.IsReadOnly = true; textBoxMessage.Background = new SolidColorBrush(Colors.Transparent); textBoxMessage.TextWrapping = TextWrapping.Wrap; textBoxMessage.BorderThickness = new Thickness(0); textBoxMessage.FontSize = 16; textBoxMessage.Text = messageInfo.content; textBoxMessage.Margin = new Thickness(0, 0, 0, 10); if (messageInfo.sender.Equals(LanguageResource.language_res.strServerManager)) { textBoxSender.HorizontalAlignment = HorizontalAlignment.Right; textBoxMessage.HorizontalAlignment = HorizontalAlignment.Right; } DockPanel.SetDock(textBoxSender, Dock.Top); DockPanel.SetDock(textBoxMessage, Dock.Top); dockPanelToShowMessage.Children.Add(textBoxSender); dockPanelToShowMessage.Children.Add(textBoxMessage); scrollViewerToShowMessage.ScrollToEnd(); })); //MessageInfo에서 xml로 변한 string 값을 다시 MessageInfo로 제작해서 넘기는건 비효율적, 하지만 일단 그렇게 하자 listOfMessage.AddLast(XMLHandlerForMessage.readXmlToGetMessage(messageInXML)); }
//서버 운영자가 클라이언트에게 메세지를 쓸 때, 전송 버튼을 누를 때 private void buttonToSendMessage_Click(object sender, RoutedEventArgs e) { try { if (textBoxToInsertMessage.Text.Trim() == "") { return; } //서버가 입력한 메세지를 XML 값으로 변경 string message = textBoxToInsertMessage.Text.Trim(); MessageInfo messageInfo = new MessageInfo("message", "Server", message, getCurrentTime(), 0 + ""); string messageInXML = XMLHandlerForMessage.convertStringToXml(messageInfo); sendMessageToConnectedClients(messageInXML); textBoxToInsertMessage.Text = ""; textBoxToInsertMessage.Focus(); } catch (Exception ex) { MessageBox.Show("buttonToSendMessage_Click에서\n " + ex.ToString()); } }