Luis Briga Posted April 11, 2024 at 11:15 PM Report #632997 Posted April 11, 2024 at 11:15 PM O meu nome é Luís e estou neste momento a desenvolver um projeto que consiste na implementação de um sistema cliente/servidor para gestão de serviços de mobilidade oferecidos pela empresa ServiMoto. Os serviços incluem verificações de árvores e jardins, intervenções de bombeiros, entregas postais e entrega de pizza. O sistema permite que clientes (bicicletas) se conectem ao servidor para receber tarefas, atualizar o status das tarefas e solicitar novas tarefas. O servidor gerencia essas solicitações, aloca tarefas aos clientes e mantém registros das tarefas e clientes alocados em arquivos CSV. O projeto é implementado em C# utilizando soquetes e o protocolo de comunicação definido. Atualmente meus dois códigos principais são estes: classe servidor: using System; using System.IO; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; class Servidor { // Objeto Mutex para garantir acesso exclusivo aos arquivos CSV static Mutex mutex = new Mutex(); // Método para atualizar o arquivo CSV com a conclusão de uma tarefa static void AtualizarTarefaConcluida(string nomeArquivo, string idTarefa) { mutex.WaitOne(); try { string[] linhas = File.ReadAllLines(nomeArquivo); for (int i = 0; i < linhas.Length; i++) { if (linhas[i].StartsWith(idTarefa)) { // Substitui "em curso" por "concluída" apenas se "em curso" estiver presente if (linhas[i].Contains("em curso")) { linhas[i] = linhas[i].Replace("em curso", "concluida"); } break; } } File.WriteAllLines(nomeArquivo, linhas); } finally { mutex.ReleaseMutex(); } } // Método para atribuir uma nova tarefa ao cliente e atualizar o arquivo CSV correspo ndente static void AlocarNovaTarefa(string nomeArquivo, string idCliente) { mutex.WaitOne(); try { // Lógica para atribuir uma nova tarefa ao cliente e atualizar o arquivo CSV // Por exemplo, pode envolver a leitura do arquivo para encontrar uma tarefa disponível e atualizar seu status } finally { mutex.ReleaseMutex(); } } static void Main(string[] args) { TcpListener servidor = null; try { // Endereço IP e porta do servidor IPAddress enderecoIp = IPAddress.Parse("127.0.0.1"); int porta = 8888; // Inicia o servidor e escuta por conexões servidor = new TcpListener(enderecoIp, porta); servidor.Start(); Console.WriteLine("Servidor iniciado..."); while (true) { // Aceita a conexão do cliente TcpClient cliente = servidor.AcceptTcpClient(); Console.WriteLine("Cliente conectado!"); // Prepara as streams de rede NetworkStream stream = cliente.GetStream(); byte[] dados = new byte[256]; StringBuilder resposta = new StringBuilder(); int bytes; // Lê os dados recebidos do cliente while ((bytes = stream.Read(dados, 0, dados.Length)) != 0) { resposta.Append(Encoding.ASCII.GetString(dados, 0, bytes)); Console.WriteLine("Mensagem recebida: {0}", resposta.ToString()); // Verifica o tipo de mensagem recebida if (resposta.ToString().StartsWith("CONNECT")) { // Responde com sucesso byte[] msg = Encoding.ASCII.GetBytes("100 OK"); stream.Write(msg, 0, msg.Length); Console.WriteLine("Resposta enviada: 100 OK"); } else if (resposta.ToString().StartsWith("TASK_COMPLETE")) { // Extrai o ID da tarefa concluída string idTarefaConcluida = resposta.ToString().Substring("TASK_COMPLETE".Length).Trim(); // Atualiza o arquivo CSV correspondente AtualizarTarefaConcluida("Servico_A.csv", idTarefaConcluida); // Responde com confirmação de conclusão da tarefa byte[] msg = Encoding.ASCII.GetBytes("TASK_COMPLETED"); stream.Write(msg, 0, msg.Length); Console.WriteLine("Resposta enviada: TASK_COMPLETED"); } else if (resposta.ToString() == "REQUEST_TASK") { // Lógica para atribuir uma nova tarefa ao cliente e atualizar o arquivo CSV // Aqui você pode chamar o método AlocarNovaTarefa() para atribuir a nova tarefa } else if (resposta.ToString() == "QUIT") { // Responde com encerramento da conexão byte[] msg = Encoding.ASCII.GetBytes("400 BYE"); stream.Write(msg, 0, msg.Length); Console.WriteLine("Resposta enviada: 400 BYE"); // Fecha a conexão cliente.Close(); break; } else { // Responde com erro byte[] msg = Encoding.ASCII.GetBytes("ERROR"); stream.Write(msg, 0, msg.Length); Console.WriteLine("Resposta enviada: ERROR"); } // Limpa o StringBuilder para a próxima mensagem resposta.Clear(); } } } catch (Exception ex) { Console.WriteLine("Erro: " + ex.Message); } finally { // Encerra o servidor servidor.Stop(); } } } classe cliente: using System; using System.Net.Sockets; using System.Text; class Cliente { static void Main(string[] args) { try { // Endereço IP e porta do servidor string servidorIp = "127.0.0.1"; int porta = 8888; // Cria uma instância do cliente TCP TcpClient cliente = new TcpClient(servidorIp, porta); Console.WriteLine("Conectado ao servidor..."); // Prepara as streams de rede NetworkStream stream = cliente.GetStream(); byte[] dados = new byte[256]; string resposta = string.Empty; Console.WriteLine("Indique o seu ID de Cliente: "); string idCliente = Console.ReadLine(); // Envia mensagem de conexão string mensagemConnect = "CONNECT"; byte[] msgConnect = Encoding.ASCII.GetBytes(mensagemConnect); stream.Write(msgConnect, 0, msgConnect.Length); Console.WriteLine("Mensagem enviada: {0}", mensagemConnect); // Lê a resposta do servidor int bytesConnect = stream.Read(dados, 0, dados.Length); resposta = Encoding.ASCII.GetString(dados, 0, bytesConnect); Console.WriteLine("Resposta recebida: {0}", resposta); while (true) { Console.WriteLine("Escolha uma opção:"); Console.WriteLine("1. Concluir tarefa"); Console.WriteLine("2. Solicitar nova tarefa"); Console.WriteLine("3. Sair"); Console.Write("Opção: "); string opcao = Console.ReadLine(); switch (opcao) { case "1": // Envia mensagem de conclusão de tarefa Console.WriteLine("Indique o ID da tarefa concluída: "); string idTarefaConcluida = Console.ReadLine(); string mensagemConclusao = $"TASK_COMPLETE <{idTarefaConcluida}>"; byte[] msgConclusao = Encoding.ASCII.GetBytes(mensagemConclusao); stream.Write(msgConclusao, 0, msgConclusao.Length); Console.WriteLine("Mensagem enviada: {0}", mensagemConclusao); // Lê a resposta do servidor int bytesConclusao = stream.Read(dados, 0, dados.Length); resposta = Encoding.ASCII.GetString(dados, 0, bytesConclusao); Console.WriteLine("Resposta recebida: {0}", resposta); break; case "2": // Envia pedido de nova tarefa string mensagemPedido = "REQUEST_TASK"; byte[] msgPedido = Encoding.ASCII.GetBytes(mensagemPedido); stream.Write(msgPedido, 0, msgPedido.Length); Console.WriteLine("Mensagem enviada: {0}", mensagemPedido); // Lê a resposta do servidor int bytesPedido = stream.Read(dados, 0, dados.Length); resposta = Encoding.ASCII.GetString(dados, 0, bytesPedido); Console.WriteLine("Resposta recebida: {0}", resposta); break; case "3": // Envia mensagem de encerramento string mensagemQuit = "QUIT"; byte[] msgQuit = Encoding.ASCII.GetBytes(mensagemQuit); stream.Write(msgQuit, 0, msgQuit.Length); Console.WriteLine("Mensagem enviada: {0}", mensagemQuit); // Lê a resposta do servidor int bytesQuit = stream.Read(dados, 0, dados.Length); resposta = Encoding.ASCII.GetString(dados, 0, bytesQuit); Console.WriteLine("Resposta recebida: {0}", resposta); // Fecha a conexão e sai do loop cliente.Close(); return; default: Console.WriteLine("Opção inválida."); break; } } } catch (Exception ex) { Console.WriteLine("Erro: " + ex.Message); } } } O problema é que quando quero declarar uma tarefa concluída usando minha função UpdateCompletedTask, o arquivo csv não muda e permanece sempre o mesmo. Alguém pode me ajudar? Alterei o código da minha função algumas vezes porque acho que o problema está na função UpdateCompletedTask mas ainda assim nada mudou.
iznougudpt Posted April 12, 2024 at 11:56 AM Report #633001 Posted April 12, 2024 at 11:56 AM Tens aí vários problemas com o modo como lês e alteras o ficheiro. Devias criar uma classe Tarefa que tenha todos os campos necessários. Em seguida usas uma classe Tarefas que tenha um array/lista das Tarefas existentes e que tenha as funções de criar, alterar ou eliminar Tarefas. Esta classe vai tratar também da leitura e escrita do ficheiro CSV, assim tens controlo total sobre o ficheiro que é usado. Na questão da leitura do ficheiro, deves fazer Split de cada linha pelo caracter que é utilizado para indicar a separação de colunas (normalmente , ou ; ) e carregar um objecto do tipo Tarefa para cada linha. Um problema dos CSV é que podes ter o caracter de separação de colunas no meio de outro texto e isso causa problemas, por isso tens sempre de ignorar todos os carateres que estejam entre ". Se implementares isto vais deixar de usar o StartsWith (pode dar problemas se por algum motivo a lista não estiver ordenada) e o Replace do estado. O campo Estado sugiro que troques o texto por um Integer (ou mesmo um Enum), é menos informação a guardar e é mais fácil gerir dentro da classe. Depois quando precisares de mostrar o texto do estado trocas nessa altura. Chegando à tua questão, o problema pode estar no StartsWith se a coluna for do tipo Texto porque por vezes tem ' no início, ou outra situação do género, mas o melhor para perceberes isso será usar a opção de Debug (Depuração) que deves ter no Compilador para que pare nessa linha e possas acompanhar o que o código efetivamente faz.
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now