The method am using to send data to a server program is triggered by a button, The string is sent and I can print it out on the window of the server console but I get an exception on the client side that cannot access a closed pipe. The method is async but the string I sent to the server is immediately printed on the server but then on the client it says that it cannot access a closed pipe. Where did I close the pipe and how can I get rid of this error? Here is how am sending data to the server
private async void button1_Click(object sender, EventArgs e)
{
// Process the input entered by the user and check if the user exists
var ip = textBox1.Text;
var pass = textBox2.Text;
if (string.IsNullOrWhiteSpace(ip) || string.IsNullOrWhiteSpace(pass))
{
MessageBox.Show("A white space input is not allowed in either of the password/username fields");
return;
}
// Make sure the server is running
var processName = "ServerProgram";
// Check if any process in the given array is running
var processes = Process.GetProcessesByName(processName);
if (processes.Length > 0)
{
try
{
// The server is running, connect and authenticate the user
using (var pipeServer = new NamedPipeClientStream(".", "ServerProgram", PipeDirection.InOut))
{
Console.WriteLine("Connecting to the server");
await pipeServer.ConnectAsync();
Console.WriteLine("Connected to the server");
// Send the IP and the account name to the server
using (var writer = new StreamWriter(pipeServer))
{
await writer.WriteAsync(string.Join("-", new string[] { ip, pass }));
await writer.FlushAsync();
}
// Disable the button after connecting to the server
// Read response from the server asynchronously (if needed)
var response = await new StreamReader(pipeServer).ReadToEndAsync();
MessageBox.Show(response);
}
}
catch (Exception ex)
{
MessageBox.Show($"Error connecting to the server: {ex.Message}");
}
}
else
{
MessageBox.Show("The Server is not running, kindly start the server and try again");
}
}
Then on the server am using an infinite while loop to listen for incoming connections from clients. I did not close the NamedServerStreamPipe because I have used a using statement to define it which means the pipe is closed after the scope is exited.
static async Task Main(string args[]){
while(true){
await Task.Run(() => HandleClient());
}
static async Task HandleClient()
{
using (var serverStream = new NamedPipeServerStream("ServerProgram", PipeDirection.InOut, NamedPipeServerStream.MaxAllowedServerInstances, PipeTransmissionMode.Byte, PipeOptions.Asynchronous))
{
try
{
await serverStream.WaitForConnectionAsync();
using (var reader = new StreamReader(serverStream, Encoding.UTF8, true, 4096, true))
using (var writer = new StreamWriter(serverStream, Encoding.UTF8, 4096, true))
{
string message = await reader.ReadLineAsync();
if (message == null)
{
// Client closed the connection
Console.WriteLine("Client closed the connection");
return;
}
Console.WriteLine(message);
var userAndPassword = message.Split('-');
if (userAndPassword.Length == 2)
{
var user = userAndPassword[0];
var pass = userAndPassword[1];
if (dataBase.ContainsKey(user))
{
Console.WriteLine(user + " found");
}
else
{
writer.WriteLine("user does not exist");
writer.Flush();
}
}
else
{
// Invalid message format
Console.WriteLine("Invalid message format");
}
}
}
catch (IOException ex) when ((ex.InnerException as System.Net.Sockets.SocketException)?.SocketErrorCode == System.Net.Sockets.SocketError.ConnectionReset)
{
// Client disconnected abruptly
Console.WriteLine("Client disconnected abruptly");
}
catch (Exception ex)
{
Console.WriteLine("Error: " + ex.Message);
}
}
}
}
What am I doing wrong for the server and client to communicate without a cannot access a closed pipe exception being thrown?
