/// <summary> /// Реализует реакцию на команду из tcp-соединения /// </summary> /// <param name="Tcp">tcp-отправителя</param> private void TcpThreadFunc(object tcp) { TcpClient Tcp = (TcpClient)tcp; try { NetStreamReaderWriter Stream = new NetStreamReaderWriter(Tcp.GetStream()); NetCommand Cmd = Stream.ReadCmd(); UiWriteLog("От " + Cmd.sender + " поступила команда '" + Cmd.cmd + "'"); // Если отправитель - другой сервер сообщений if (Cmd.sender == "msgserver") { ServerCommandHandler(Stream, Cmd); } // Если отправитель - диспетчер else if (Cmd.sender == "dispatcher") { DispatcherCommandHandler(Stream, Cmd); } // Если отправитель - клиент else { ClientCommandHandler(Stream, Cmd); } } catch (Exception ex) { Debug.Write(" > Ошибка в TcpThreadFunc: " + ex.Message); } }
/// <summary> /// Рассылает сообщение всем серверам из списка /// </summary> /// <param name="Sender">отправитель сообщения</param> /// <param name="Msg">текст сообщения</param> private void SendMsgToAllServers(string Sender, string Msg) { lock (m_ServersList) { for (int i = 0; i < m_ServersList.Count; i++) { try { string ServerIP = m_ServersList[i].GetIP(); int ServerPort = m_ServersList[i].GetPort(); if ((ServerIP == m_ServerIP.ToString()) && (ServerPort == m_ServerPort)) continue; TcpClient Tcp = new TcpClient(ServerIP, ServerPort); NetStreamReaderWriter Stream = new NetStreamReaderWriter(Tcp.GetStream()); NetCommand Cmd = CreateCommand("!message", Sender + ": " + Msg); //UiWriteLog("Посылаем команду '" + Cmd.cmd + " " + Cmd.parameters + "' на " + ServerIP + ":" + ServerPort.ToString()); Stream.WriteCmd(Cmd); NetCommand AnsCmd = Stream.ReadCmd(); //UiWriteLog("Получили ответ '" + AnsCmd.cmd + " " + AnsCmd.parameters + "' от " + AnsCmd.Ip + ":" + AnsCmd.Port); } catch (Exception ex) { Debug.Write(" > Ошибка в SendMsgToAllServers: " + ex.Message); } } } }
//посылка сообщения private void AsyncSendMessage(string mes) { Thread t = new Thread(() => { try { TcpClient tcp = new TcpClient(serverIp, serverPort); NetStreamReaderWriter nsrw = new NetStreamReaderWriter(tcp.GetStream()); sendMessage(nsrw, mes); NetCommand ansMessage = nsrw.ReadCmd(); if (ansMessage.cmd != "!ok") { throw new Exception(" Вместо подтверждения получено что-то другое"); } } catch (Exception ex) { Debug.WriteLine("Client. ClientForm. AsyncSendMessage." + ex.Message); } } ); t.Start(); }
private void getFileListFromServer(NetworkStream ns) { NetStreamReaderWriter nsrw = new NetStreamReaderWriter(ns); NetCommand getFileListCmd = new NetCommand() { Ip = myIp.ToString(),//Dns.GetHostAddresses(Dns.GetHostName())[0].ToString(), Port = ListenerPort, sender = name, cmd = "!getfilelist", parameters = "" }; nsrw.WriteCmd(getFileListCmd); NetCommand ansGetFileList = nsrw.ReadCmd(); //ответ string[] files = ansGetFileList.parameters.Split(new char[] { '|' }); //получили массив имен lock (lbFilesList) //Ui { ClearFilesD(); foreach (String s in files) { AddFileD(s); } } }
private void getContactListFromServer(NetworkStream ns) { NetStreamReaderWriter nsrw = new NetStreamReaderWriter(ns); NetCommand getClientListCmd = new NetCommand() { Ip = myIp.ToString(),//Dns.GetHostAddresses(Dns.GetHostName())[0].ToString(), Port = ListenerPort, sender = name, cmd = "!getclientlist", parameters = "" }; nsrw.WriteCmd(getClientListCmd); NetCommand ansGetClientList = nsrw.ReadCmd(); //получение ответа string[] names = ansGetClientList.parameters.Split(new char[] { '|' }); //получили массив имен lock (lbPeople) //работа с Ui { lbPeople.Invoke(ClearPeopleD); foreach (String s in names) { lbPeople.Invoke(AddManD, new object[] { s }); } } }
//регистрация на сервере (через диспетчер или напрямую) private bool registerMe(string name) { TcpClient tcpClient = new TcpClient(serverIp, serverPort); NetStreamReaderWriter nsrw = new NetStreamReaderWriter(tcpClient.GetStream()); try { NetCommand registerCmd = new NetCommand() { Ip = myIp.ToString(), //Dns.GetHostAddresses(Dns.GetHostName())[0].ToString(), Port = ListenerPort, sender = name, //пока что безымянный cmd = "!register", parameters = name }; nsrw.WriteCmd(registerCmd); NetCommand ansRegisterCmd = nsrw.ReadCmd(); return(ansRegisterCmd.cmd == "!registred"); } catch (Exception ex) { MessageBox.Show("Не удалось зарегистрироваться на сервере, т.к. сервер не отвечает"); Debug.WriteLine("Client. ClientForm. registerMe " + ex.Message); return(false); } }
private void sendMessage(NetStreamReaderWriter nsrw, string mes) { NetCommand messageCmd = new NetCommand() { Ip = myIp.ToString(), //Dns.GetHostAddresses(Dns.GetHostName())[0].ToString(), Port = ListenerPort, sender = name, //пока что безымянный cmd = "!message", parameters = mes }; nsrw.WriteCmd(messageCmd); }
/// <summary> /// Обработчик команды сервера /// </summary> /// <param name="Stream">поток</param> /// <param name="Cmd">команда</param> private void ServerCommandHandler(NetStreamReaderWriter Stream, NetCommand Cmd) { try { switch (Cmd.cmd) { // Принимает сообщение case "!message": { Stream.WriteCmd(CreateCommand("!ok", "Вас понял!")); UiWriteLog(Cmd.parameters); SendMsgToAllClients("!msgserver", Cmd.parameters); } break; case "!clientregistred": case "!clientunregistred": { Stream.WriteCmd(CreateCommand("!ok", "Вас понял!")); Cmd.sender = "!msgserver"; Cmd.Ip = m_ServerIP.ToString(); Cmd.Port = m_ServerPort; SendCmdToAllClients(Cmd); } break; case "!serverregistred": case "!serverunregistred": { Stream.WriteCmd(CreateCommand("!ok", "Вас понял!")); } break; // Неизвестная команда default: { Stream.WriteCmd(CreateCommand("!unknowncommand", "К сожалению сервер не знает такой команды")); UiWriteLog("Такая команда неизвестна серверу!"); } break; } } catch (Exception ex) { Debug.Write(" > Ошибка в ServerCommandHandler: " + ex.Message); } }
//Пингование void AsyncStartPing() { Thread t = new Thread(() => { try { while (true) { TcpClient tcpClient = new TcpClient(serverIp, serverPort); NetStreamReaderWriter nsrw = new NetStreamReaderWriter(tcpClient.GetStream()); nsrw.ReadTimeout = 2000; NetCommand pingCmd = new NetCommand() { Ip = myIp.ToString(), //Dns.GetHostAddresses(Dns.GetHostName())[0].ToString(), Port = ListenerPort, sender = name, //пока что безымянный cmd = "!ping", parameters = "" }; nsrw.WriteCmd(pingCmd); NetCommand ansPing = nsrw.ReadCmd(); if (ansPing.cmd != "!pong") { MessageBox.Show("Client. В ответ на пинг пришла хрень"); } tcpClient.Close(); Thread.Sleep(1000); //задержка } } catch (Exception ex) { MessageBox.Show("Client. Сервер не отвечает на пинг"); connected = false; lock (lbPeople) { lbPeople.Invoke(UpdateConnectedD); } } }); t.Start(); }
/// <summary> /// Отослать команду /// </summary> /// <param name="cmd">команда</param> /// <param name="param">параметры</param> /// <returns>ответ</returns> private NetCommand SendCommand(string cmd, string param, string ip, int port) { NetCommand retn = null; try { TcpClient tcpclient = new TcpClient(ip, port); NetStreamReaderWriter Stream = new NetStreamReaderWriter(tcpclient.GetStream()); //UiWriteLog("Посылаем команду '" + cmd + " " + param + "' на " + ip + ":" + port.ToString()); Stream.WriteCmd(CreateCommand(cmd, param)); retn = Stream.ReadCmd(); //UiWriteLog("Получили ответ '" + retn.cmd + " " + retn.parameters + "' от " + retn.Ip + ":" + retn.Port); } catch (Exception ex) { Debug.Write(" > Ошибка в SendCommand: " + ex.Message); } return retn; }
/// <summary> /// Рассылает команды всем клиентам из списка /// </summary> /// <param name="Cmd">команда</param> private void SendCmdToAllClients(NetCommand Cmd) { lock (m_ClientsList) { for (int i = 0; i < m_ClientsList.Count; i++) { try { string ClientIP = m_ClientsList[i].GetIP(); int ClientPort = m_ClientsList[i].GetPort(); TcpClient Tcp = new TcpClient(ClientIP, ClientPort); NetStreamReaderWriter Stream = new NetStreamReaderWriter(Tcp.GetStream()); //UiWriteLog("Посылаем команду '" + Cmd.cmd + " " + Cmd.parameters + "' на " + ClientIP + ":" + ClientPort.ToString()); Stream.WriteCmd(Cmd); NetCommand AnsCmd = Stream.ReadCmd(); //UiWriteLog("Получили ответ '" + AnsCmd.cmd + " " + AnsCmd.parameters + "' от " + AnsCmd.Ip + ":" + AnsCmd.Port); } catch (Exception ex) { Debug.Write(" > Ошибка в SendCmdToAllClients: " + ex.Message); } } } }
/// <summary> /// Обработчик клиентской команды /// </summary> /// <param name="Stream">читатель-писатель</param> /// <param name="Cmd">команда</param> private void ClientCommandHandler(NetStreamReaderWriter Stream, NetCommand Cmd) { try { switch (Cmd.cmd) { // Инициализация, или "кому я пишу?" case "!who": { Stream.WriteCmd(AnsWho()); } break; // Регистрация клиента case "!register": { Stream.WriteCmd(AnsRegister(Cmd)); } break; // Сообщение всем клиентам case "!message": { Stream.WriteCmd(CreateCommand("!ok", "Вас понял")); SendMsgToAllClients(Cmd.sender, Cmd.parameters); SendMsgToAllServers(Cmd.sender, Cmd.parameters); } break; // Запрос списка контактов case "!getclientlist": { Stream.WriteCmd(AnsClientList()); } break; // Запрос списка файлов case "!getfilelist": { Stream.WriteCmd(AnsFileList()); } break; // Запрос свободного файлового сервера для закачки case "!getfreefileserver": { Stream.WriteCmd(AnsFreeFileServer()); } break; // Запрос файлового сервера для скачки case "!getfileserver": { Stream.WriteCmd(AnsFileServer(Cmd.parameters)); } break; // Пинг от клиента case "!ping": { Stream.WriteCmd(CreateCommand("!pong", "Я тут")); UpdatePingTime(Cmd.sender); } break; // Неизвестная команда default: { Stream.WriteCmd(CreateCommand("!unknowncommand", "К сожалению сервер не знает такой команды")); UiWriteLog("Такая команда неизвестна серверу!"); } break; } } catch (Exception ex) { Debug.Write(" > Ошибка в ClientCommandHandler: " + ex.Message); } }
/// <summary> /// Обработчик команды диспетчера /// </summary> /// <param name="Stream">поток</param> /// <param name="Cmd">команда</param> private void DispatcherCommandHandler(NetStreamReaderWriter Stream, NetCommand Cmd) { try { switch (Cmd.cmd) { // Зарегистрировался новый сервер case "!serverregistered": { string[] param = Cmd.parameters.Split(new char[] { ' ' }); if (param.Length < 2) { UiWriteLog("Неверный формат команды"); break; } string ip = param[0]; string port = param[1]; Stream.WriteCmd(AnsAddServer(ip, int.Parse(port))); } break; // Сервер разрегистрировался case "!serverunregistered": { string[] param = Cmd.parameters.Split(new char[] { ' ' }); if (param.Length < 2) { UiWriteLog("Неверный формат команды"); break; } string ip = param[0]; string port = param[1]; Stream.WriteCmd(AnsDeleteServer(ip, int.Parse(port))); } break; // Регистрация и анрегистрация клиентов case "!clientregistered": case "!clientunregistered": Stream.WriteCmd(CreateCommand("!ok", "Вас понял!")); NetCommand CloneCmd = Cmd.Clone(); CloneCmd.Ip = m_ServerIP.ToString(); CloneCmd.Port = m_ServerPort; CloneCmd.sender = "msgserver"; SendCmdToAllClients(CloneCmd); break; // Неизвестная команда default: { Stream.WriteCmd(CreateCommand("!unknowncommand", "К сожалению сервер не знает такой команды")); UiWriteLog("Такая команда неизвестна серверу!"); } break; } } catch (Exception ex) { Debug.Write(" > Ошибка в DispatcherCommandHandler: " + ex.Message); } }
private void butConnect_Click(object sender, EventArgs e) { if (!IpIsValid()) { return; } if (tbName.Text.Trim() == String.Empty) { MessageBox.Show("Имя не должно быть пустым!"); return; } //передаем параметры сервера serverIp = tbIp.Text; serverPort = Convert.ToInt32(numericUpDownPort.Value); MyPort = getFreeListenerPort(out this.tcpListener);//включение листенера, получение порта try { TcpClient tcpClient = new TcpClient(tbIp.Text, Convert.ToInt32(numericUpDownPort.Value)); NetStreamReaderWriter nsrw = new NetStreamReaderWriter(tcpClient.GetStream()); NetCommand whoCmd = new NetCommand() { Ip = cmbClientIp.Text, //Dns.GetHostAddresses(Dns.GetHostName())[0].ToString(), Port = MyPort, sender = "client", //пока что безымянный cmd = "!who", parameters = "" }; nsrw.WriteCmd(whoCmd); NetCommand ansWhoCmd = nsrw.ReadCmd(); //если через диспетчера if (ansWhoCmd.cmd == "!dispatcher") { NetCommand getserverCmd = new NetCommand() { Ip = cmbClientIp.Text, //Dns.GetHostAddresses(Dns.GetHostName())[0].ToString(), Port = MyPort, sender = "client", //пока что безымянный cmd = "!getserver", parameters = "" }; nsrw.WriteCmd(getserverCmd); NetCommand ansServerAddress = nsrw.ReadCmd();//ждем ответ if (ansServerAddress.cmd == "!hasnotserver") { MessageBox.Show("А нету серверов!"); return; } if (ansServerAddress.cmd != "!msgserver") { MessageBox.Show("Вместо адреса сервера получена шняга", "Какая-то фигня"); return; } String[] adr = ansServerAddress.parameters.Split(new char[] { ' ' }); TcpClient tcpToServer = new TcpClient(adr[0], Convert.ToInt32(adr[1])); //коннектимся к серверу nsrw = new NetStreamReaderWriter(tcpToServer.GetStream()); nsrw.WriteCmd(whoCmd); ansWhoCmd = nsrw.ReadCmd(); serverIp = adr[0]; serverPort = Convert.ToInt32(adr[1]); } if (ansWhoCmd.cmd != "!messageserver") { throw new Exception("Не найден сервер обмена сообщениями"); } this.tcpClient = tcpClient; this.DialogResult = DialogResult.OK; } catch (Exception ex) { MessageBox.Show(ex.Message); } }
private void Listen(Object tcpCliento)//обработка команды { TcpClient tcpClient = (TcpClient)tcpCliento; NetStreamReaderWriter nsrw = new NetStreamReaderWriter(tcpClient.GetStream()); if (tcpClient.Connected) { try { NetCommand command = nsrw.ReadCmd(); switch (command.cmd) { case "!message": //прием сообщения string message = command.parameters; nsrw.WriteCmd(CreateStandardAnswer()); //ответ { lock (tbChat) { tbChat.Invoke(WriteMessageD, new object[] { message }); } //WriteMessage(message);//обновление уи } break; case "!clientregistered": nsrw.WriteCmd(CreateStandardAnswer()); //ответ string cl = command.parameters; lock (lbPeople) { lbPeople.Invoke(AddManD, new object[] { cl }); //AddManD(cl); } break; case "!clientunregistered": nsrw.WriteCmd(CreateStandardAnswer()); //ответ cl = command.parameters; lock (lbPeople) { lbPeople.Invoke(RemoveManD, new object[] { cl }); //RemoveManD(cl); } break; case "!addfile": nsrw.WriteCmd(CreateStandardAnswer()); //ответ string file = command.parameters; lock (lbFilesList) { lbFilesList.Invoke(AddFileD, new object[] { file }); //AddFileD(file); } break; case "!deletefile": nsrw.WriteCmd(CreateStandardAnswer()); //ответ file = command.parameters; lock (lbFilesList) { lbFilesList.Invoke(RemoveFileD, new object[] { file }); //RemoveFileD(file); } break; default: MessageBox.Show("неизвестная команда!"); break; } } catch (IOException ex) { System.Diagnostics.Debug.WriteLine("Client. за 20 сек сервер ничего не сказал"); } } }