I am building a bare bones program that simple delivers a message from server to client.
Now i am successfully able to establish connection between the server and client, however the client program is unable to read from the stream. Here's my code.
Code for server program
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.Net.Sockets;
namespace chat_client_console
{
class Program
{
static TcpListener listener;
static void Main(string[] args)
{
string name = Dns.GetHostName();
IPAddress[] address = Dns.GetHostAddresses(name);
/*
foreach(IPAddress addr in address)
{
Console.WriteLine(addr);
}*/
Console.WriteLine(address[1].ToString());
listener = new TcpListener(address[1], 2055);
listener.Start();
Socket soc = listener.AcceptSocket();
Console.WriteLine("Connection successful");
Stream s = new NetworkStream(soc);
StreamReader sr = new StreamReader(s);
StreamWriter sw = new StreamWriter(s);
sw.AutoFlush = true;
sw.Write("A test message");
Console.WriteLine("Test message delivered. Now ending the program");
/*
string name = Dns.GetHostName();
Console.WriteLine(name);
//IPHostEntry ip = Dns.GetHostEntry(name);
//Console.WriteLine(ip.AddressList[0].ToString());
IPAddress[] adr=Dns.GetHostAddresses(name);
foreach (IPAddress adress in adr)
{
Console.WriteLine(adress);
}
*/
Console.ReadLine();
}
}
}
and here's the code from the client program
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Net.Sockets;
namespace chat_client_console_client
{
class Program
{
static void Main(string[] args)
{
string display;
TcpClient client = new TcpClient("localhost", 2055);
Stream s = client.GetStream();
Console.WriteLine("Connection successfully received");
StreamWriter sw = new StreamWriter(s);
StreamReader sr = new StreamReader(s);
sw.AutoFlush = true;
while (true)
{
display = sr.ReadLine();
Console.WriteLine("Reading stream");
if (display == "")
{
Console.WriteLine("breaking stream");
break;
}
}
Console.WriteLine(display);
}
}
}
now i am successfully able to establish connection between the programs as indicated by various check messages. The server program is also successfully able to send the data into the stream.
However the client program is unable to read data from the stream. It seems to be stuck at readline() function.
Now i have been banging my head against the wall on this problem for hours now and would be greatly thankful if somebody is able to help me.
Look at your server:
sw.AutoFlush = true;
sw.Write("A test message");
You're never writing a line break, which is what the client is waiting to see.
Related
Take a look at the following two programs:
//Server
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace MyServerProgram
{
class Program
{
static void Main(string[] args)
{
IPAddress ip = IPAddress.Parse("127.0.0.1");
int port = 2000;
TcpListener listener = new TcpListener(ip, port);
listener.Start();
TcpClient client = listener.AcceptTcpClient();
NetworkStream netStream = client.GetStream();
BinaryReader br = new BinaryReader(netStream);
try
{
while (client.Client.Connected)
{
string str = br.ReadString();
Console.WriteLine(str);
}
}
catch
{
br.Close();
netStream.Close();
client.Close();
listener.Stop();
}
}
}
}
//Client
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace MyClientProgram
{
class Program
{
static void Main(string[] args)
{
int port = 2000;
TcpClient client = new TcpClient("localhost", port);
NetworkStream netStream = client.GetStream();
BinaryWriter br = new BinaryWriter(netStream);
try
{
int i=1;
while (client.Client.Connected)
{
br.Write(i.ToString());
br.Flush();
i++;
int milliseconds = 2000;
System.Threading.Thread.Sleep(milliseconds);
}
}
catch
{
br.Close();
netStream.Close();
client.Close();
}
}
}
}
These programs are working fine.
Suppose, at this point of this program, I need the server to print a message on the screen as soon as a client gets connected to it, and, also when the client is disconnected.
How can I do that?
AcceptTcpClient blocks execution and starts waiting for connection. So right after it you can write message that client connected. Also you could write connected client address. Just for information, but sometimes it could be helpful.
TcpClient client = listener.AcceptTcpClient();
ShowMessage("Connected " + ((IPEndPoint)client.Client.RemoteEndPoint).Address);
For detect client disconnect you could catch exceptions. Change your catch like this:
catch (Exception ex) {
var inner = ex.InnerException as SocketException;
if (inner != null && inner.SocketErrorCode == SocketError.ConnectionReset)
ShowMessage("Disconnected");
else
ShowMessage(ex.Message);
...
Here is a sample server and client code in c#. The server will send an array of string and the client will receive it and display and then the client will send an id and the server will receive it and display. But I am getting an exception in my the server while running both of them.
The exception is as follows:
An unhandled exception of type 'System.ObjectDisposedException' occurred in System.dll
Additional information: Cannot access a disposed object.
Client:
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Text;
using System.Xml.Serialization;
namespace Client
{
class Program
{
static void Main(string[] args)
{
try
{
byte[] data = new byte[1024];
string stringData;
TcpClient tcpClient = new TcpClient("127.0.0.1", 1234);
NetworkStream ns = tcpClient.GetStream();
var serializer = new XmlSerializer(typeof(string[]));
var stringArr = (string[])serializer.Deserialize(tcpClient.GetStream());
foreach (string s in stringArr)
{
Console.WriteLine(s);
}
string input = Console.ReadLine();
ns.Write(Encoding.ASCII.GetBytes(input), 0, input.Length);
ns.Flush();
}
catch (Exception e)
{
Console.Write(e.Message);
}
Console.Read();
}
}
}
Server:
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Text;
using System.Xml.Serialization;
namespace server
{
class Program
{
static void Main(string[] args)
{
TcpListener tcpListener = new TcpListener(IPAddress.Any, 1234);
tcpListener.Start();
while (true)
{
TcpClient tcpClient = tcpListener.AcceptTcpClient();
byte[] data = new byte[1024];
NetworkStream ns = tcpClient.GetStream();
string[] arr1 = new string[] { "one", "two", "three" };
var serializer = new XmlSerializer(typeof(string[]));
serializer.Serialize(tcpClient.GetStream(), arr1);
tcpClient.Close();
int recv = ns.Read(data, 0, data.Length); //getting exception in this line
string id = Encoding.ASCII.GetString(data, 0, recv);
Console.WriteLine(id);
}
}
}
}
Is there anything wrong?
What will I need to change to avoid this exception?
Once you call
tcpClient.Close();
it cleans up resources associated with it, including disposing ns.
The following line
int recv = ns.Read(data, 0, data.Length); //getting exception in this line
attempts to read from ns after you just (indirectly) disposed of it.
Do not close the connection until you are done with it. Also, use the using keyword instead of explicitly closing the connection, as it will ensure proper cleanup even if an exception is thrown.
Read Gmail Email Attachment And Move To Any Folder In My Computer Using Console Application in c# Only..I tried POp3Client,TCpclient & Smtp..they all are working in web application..But I only need console application in c#
Here is my code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Net.NetworkInformation;
using System.Net.Security;
using System.Net.Sockets;
namespace FetchEmailFromGmail
{
class Program
{
static void Main(string[] args)
{
// create an instance of TcpClient
TcpClient tcpclient = new TcpClient();
tcpclient.Connect("pop.gmail.com", 995);
System.Net.Security.SslStream sslstream = new SslStream(tcpclient.GetStream());
sslstream.AuthenticateAsClient("pop.gmail.com");
StreamWriter sw = new StreamWriter(sslstream);
System.IO.StreamReader reader = new StreamReader(sslstream);
sw.WriteLine("USER someaccount#gmail.com"); sw.Flush();
sw.WriteLine("PASS somepass"); sw.Flush();
//sw.WriteLine("RETR 1");
//sw.WriteLine("STAT ");
sw.WriteLine("LIST ");
sw.Flush();
sw.WriteLine("Quit ");
sw.Flush();
string str = string.Empty;
string strTemp = string.Empty;
while ((strTemp = reader.ReadLine()) != null)
{
if (".".Equals(strTemp))
{
break;
}
if (strTemp.IndexOf("-ERR") != -1)
{
break;
}
str += strTemp;
}
Console.Write(str);
reader.Close();
sw.Close();
tcpclient.Close(); // close the connection
Console.ReadLine();
}
}
}
I am trying to use named pipes to communicate between a server and a client process on the same machine. server sends a message to client, client does something with it and returns a result, and server is supposed to get the result.
here is the code for server:
using System;
using System.IO;
using System.IO.Pipes;
class PipeServer
{
static void Main()
{
using (NamedPipeServerStream pipeServer =
new NamedPipeServerStream("testpipe", PipeDirection.InOut))
{
Console.WriteLine("NamedPipeServerStream object created.");
// Wait for a client to connect
Console.Write("Waiting for client connection...");
pipeServer.WaitForConnection();
Console.WriteLine("Client connected.");
try
{
// Read user input and send that to the client process.
using (StreamWriter sw = new StreamWriter(pipeServer))
{
sw.AutoFlush = true;
Console.Write("Enter text: ");
sw.WriteLine(Console.ReadLine());
}
pipeServer.WaitForPipeDrain();
using (StreamReader sr = new StreamReader(pipeServer))
{
// Display the read text to the console
string temp;
// Wait for result from the client.
while ((temp = sr.ReadLine()) != null)
{
Console.WriteLine("[CLIENT] Echo: " + temp);
}
}
}
// Catch the IOException that is raised if the pipe is
// broken or disconnected.
catch (IOException e)
{
Console.WriteLine("ERROR: {0}", e.Message);
}
}
}
}
and here is the code for client:
using System;
using System.IO;
using System.IO.Pipes;
class PipeClient
{
static void Main(string[] args)
{
using (NamedPipeClientStream pipeClient =
new NamedPipeClientStream(".", "testpipe", PipeDirection.InOut))
{
// Connect to the pipe or wait until the pipe is available.
Console.Write("Attempting to connect to pipe...");
pipeClient.Connect();
Console.WriteLine("Connected to pipe.");
Console.WriteLine("There are currently {0} pipe server instances open.",
pipeClient.NumberOfServerInstances);
using (StreamReader sr = new StreamReader(pipeClient))
{
// Display the read text to the console
string temp;
while ((temp = sr.ReadLine()) != null)
{
Console.WriteLine("Received from server: {0}", temp);
}
}
// send the "result" back to the Parent process.
using (StreamWriter sw = new StreamWriter(pipeClient))
{
sw.AutoFlush = true;
sw.WriteLine("Result");
}
pipeClient.WaitForPipeDrain();
}
Console.Write("Press Enter to continue...");
Console.ReadLine();
}
}
But in the server code, on line pipeServer.WaitForPipeDrain(); I get an ObjectDisposedException and it says "cannot access a closed pipe."
I also get the same error in the client code on when setting sw.AutoFlush to true.
Basically I couldn't find an example of duplex named pipe in c#. I either need that, or an example of anonynous pipe, with two pipes one for reading and one for writting between a parent and a child process.
Thanks in Advance.
The Problem is the using block of the StreamWriter, which will close the underlying Stream (which is your pipe here). If you don't use that block it should work.
You could do the following:
using (var pipeServer = new NamedPipeServerStream("testpipe", PipeDirection.InOut))
using (var streamReader = new StreamReader(pipeServer))
using (var streamWriter = new StreamWriter(pipeServer))
{
// ... Your code ..
}
As Johannes Egger pointed out, the StreamWriter flushes the stream on Dispose(), so the StreamWriter should be disposed first and thus be the inner-most object to dispose.
I am trying to send a message between 2 computers. I have been able to establish connection but for some weird reason i have been unable to acquire stream.
Server Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.IO;
namespace chat_server
{
class Program
{
static void Main(string[] args)
{
TcpListener server = new TcpListener(IPAddress.Any, 9999);
server.Start();
Console.WriteLine("Waiting for client connections");
TcpClient client = server.AcceptTcpClient();
Console.WriteLine("Client request accepted");
NetworkStream stream = client.GetStream();
StreamReader reader = new StreamReader(stream);
StreamWriter writer = new StreamWriter(stream);
Console.WriteLine("The message is " + reader.ReadToEnd());
}
}
}
Client Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.IO;
namespace chat_client
{
class Program
{
static void Main(string[] args)
{
TcpClient client = new TcpClient("localhost", 9999);
NetworkStream stream = client.GetStream();
StreamReader reader = new StreamReader(stream);
StreamWriter writer = new StreamWriter(stream);
writer.Write("Hello world");
Console.WriteLine("Message Sent");
Console.ReadKey();
}
}
}
My server code confirms client connection by printing client request accepted. However for some reason i am unable to acquire data from stream. Quick Help would be really appreciated.
Thank you
You need to flush the stream in order to actually send the data.
Try:
writer.Write("Hello world");
writer.Flush();
Take a look at the MSDN docs for more information:
Synchronous socket server: http://msdn.microsoft.com/en-us/library/6y0e13d3.aspx
Asynchronous socket server: http://msdn.microsoft.com/en-us/library/5w7b7x5f.aspx
Here's a site that explains in more detail the ins and outs of sockets: http://nitoprograms.blogspot.co.uk/2009/04/tcpip-net-sockets-faq.html
In server side,
add static TcpListener server; at the top
Then `server.Start();
Socket soc = listener.AcceptSocket();
Console.WriteLine("Connection successful");
Stream s = new NetworkStream(soc);
StreamReader reader = new StreamReader(s);
StreamWriter writer= new StreamWriter(s);
sw.AutoFlush = true;
sw.WriteLine("hello world");`
In client side
TcpClient client = new TcpClient("localhost", 9999);
Stream s = client.GetStream();
Console.WriteLine("Connection successfully received");
StreamWriter writer = new StreamWriter(s);
StreamReader reader = new StreamReader(s);
sw.AutoFlush = true;
string dis=reader.readLine();
Console.WriteLine(dis);
Hope it will work now.