After several attempts I can't get StreamWriter to build / work corectly so I am doing something fundamentally wrong (C#, Visual Studio)
I have an exisitng TCP Client which connects and acts as a reader, this is working without fault -
private System.Net.Sockets.NetworkStream ns;
private System.IO.StreamReader sr;
private string strIP;
private string strPort;
public System.Net.Sockets.TcpClient tc;
public Socketclient(Reader.Search objSearch)
{
m_search = objSearch;
}
public void EthernetConnection()
{
try
{
bool flag = !System.IO.File.Exists(System.Windows.Forms.Application.StartupPath + "\\IPAddress.txt");
if (!flag)
{
System.IO.TextReader textReader = System.IO.File.OpenText(System.Windows.Forms.Application.StartupPath + "\\IPAddress.txt");
string s = textReader.ReadLine();
textReader.Close();
char[] chArr = new char[] { ';' };
string[] sArr = s.Split(chArr);
strPort = sArr[0];
strIP = sArr[1];
flag = strIP == System.String.Empty || strPort == System.String.Empty;
if (!flag)
{
int i = System.Convert.ToInt16(strPort);
tc = new System.Net.Sockets.TcpClient(strIP, i);
flag = !tc.Connected;
if (!flag)
{
ns = tc.GetStream();
sr = new System.IO.StreamReader(ns);
m_search.threadClient = new System.Threading.Thread(new System.Threading.ThreadStart(ReceiveData));
m_search.threadClient.Priority = System.Threading.ThreadPriority.Lowest;
m_search.threadClient.Name = "Ethernet Thread";
}
I then want to add (in another .cs which is part of the same application) a StreamWriter thread to write back some characters to the same port and then close the StreamWriter thread (leaving the reader running) -
private System.IO.StreamWriter sw;
string line = "TH1/r/n";
using (StreamWriter sw = new StreamWriter(ns));
sw.WriteLine(line);
sw.Flush();
sw.Close();
Which, somehow (I think) needs to refer back to
ns = tc.GetStream();
Any thougts appreciated
Regards
Active
this sort of question has been asked many times already.
Receving and sending data in C#
brief cut and past from example above showing sending of data
using(TcpClient tcpClient = new TcpClient("ADDRESS"))
{
NetworkStream networkStream = tcpClient.GetStream();
using(StreamWriter streamWriter = new StreamWriter(networkStream))
{
streamWriter.WriteLine(data);
}
}
The issue was the using block around StreamWriter, removing it allowed the underlying stream to continue.
Related
My code as follows:
static void Main(string[] args)
{
TcpListener listener = new TcpListener(System.Net.IPAddress.Any, 8081);
listener.Start();
Console.WriteLine("- Waiting for a connection..... .");
TcpClient client = listener.AcceptTcpClient();
while (true)
{
//Console.WriteLine("Waiting for a connection.");
//TcpClient client = listener.AcceptTcpClient();
Console.WriteLine("Client accepted.");
NetworkStream stream = client.GetStream();
StreamReader sr = new StreamReader(client.GetStream());
StreamWriter sw = new StreamWriter(client.GetStream());
try
{
byte[] buffer = new byte[4096];
stream.Read(buffer, 0, buffer.Length);
int recv = 0;
foreach (byte b in buffer)
{
if (b != 0)
{
recv++;
}
}
string data = Encoding.UTF8.GetString(buffer, 0, recv);
//
var result = data.Split(new string[] { cr }, StringSplitOptions.None);
System.Threading.Thread.Sleep(1000);
sw.WriteLine("Hello Client, This is server");
sw.Flush();
sw.WriteLine works just fine here, but when I try to call it from another function
public static void Send()
{
sw.Writeline("Sending this from send function");
}
I get an error saying
(Error 9 The name 'sw' does not exist in the current context).
I couldn't figure out the right way to call it since sw StreamWriter uses stream() and stream uses (client) while the client uses (listener), this got beyond my very humble understanding of c#, I spent 2 days trying and researching before posting but with no luck.
Thanks
You are defining the StreamWriter in the scope of the while loop. Outside of it it does not exist. Try defining the StreamWriter as a parameter part of the class and only assign it later.
Change this:
StreamReader sr = new StreamReader(client.GetStream());
StreamWriter sw = new StreamWriter(client.GetStream());
To This:
static StreamReader sr = null;
static StreamWriter sw = null;
static void Main(string[] args)
{
...
while (true){
...
sr = new StreamReader(client.GetStream());
sw = new StreamWriter(client.GetStream());
}
}
I'm trying to make betting program in C#, storing the user's data in a txt file. I have no problem reading the data from it. However, I can't manage to overwrite it.
From what I've tested, if I call the StreamWriter part alone the overwriting happens just fine. When I put the same code after the StreamReader part, the code will reach the Console.WriteLine("reached"); line and ignore everything after it (username is never written in the console). No error is detected and compilation won't stop either.
Here's the class code:
class Dinero
{
private List<string> data;
private string path = #"C:\Users\yy\Documents\Visual Studio 2015\Projects\ErikaBot\ErikaBot\img\bank_data.txt";
...
some other methods here
...
public void thing(string username, int money)
{
FileStream fs = new FileStream(path, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None);
data = new List<string>();
using (StreamReader sr = new StreamReader(fs))
{
string a = sr.ReadLine();
for (int i = 0; a != null; i++)
{
if (a != username)
{
data.Add(a);
}
else i++;
a = sr.ReadLine();
}
}
string b = Convert.ToString(money);
Console.WriteLine("reached");
using (StreamWriter tw = new StreamWriter(fs))
{
Console.WriteLine(username);
if (data != null)
{
for (int i = 0; i < data.Count; i++)
{
tw.WriteLine(data.ElementAt(i));
}
}
string money2 = Convert.ToString(money);
tw.WriteLine(username);
tw.WriteLine(money2);
}
}
}
By disposing StreamReader you also dispose the FileStream.
Either repeat the filestream initialisation before the using statement for StreamWriter or put the latter in the using statement for StreamReader.
I'm using a C# NetworkStream to read/write to an IP address (not a DNS address).
My program is replacing a very old assembly language program that was on a mainframe. Now it's on Windows.
I'm writing/reading less than 200 bytes. The strings end with a LineFeed character so I'm using a StreamReader.Readline() to read a response, after my Stream.Write(). On the IBM a write/read cycle took 300ms.
Now about after every 2nd or 3 read, it takes 15 seconds for the read. When I read the log of the sender it is sending the data in less than a second. For some reason I get these 15 second delays.
I'm clueless on what's happening.
p.s.
One weird thing I noticed if I set the stream read timeout to 4 seconds, it times out around 4 seconds. If I set the timeout to 10 seconds or no timeout, it times out after 15 seconds.
TcpClient tcpc = null;
NetworkStream stream = null;
StreamReader sr = null;
tcpc = new TcpClient();
tcpc.NoDelay = true;
tcpc.ExclusiveAddressUse = false;
tcpc.Connect("172.18.10.100", 4004);
stream = tcpc.GetStream();
sr = new StreamReader(stream, Encoding.ASCII);
sr.Peek();
string Message = null;
Message = "IX3543543" + '\r';
stream.Write(Encoding.ASCII.GetBytes(Message), 0, Message.Length);
string readmsg = null;
for (int i = 0; i < 4; i++)
readmsg = sr.ReadLine();
Your connection stays open as your code never free your IDisposable resources.
I think that your code should run faster if you add the using constructure.
Also you can merge declaration and assignment, like this (this is only a style comment, the main concern is `IDisposable usage)
And you can ReadToEnd your message in return, and examine it by youself after releasing the resources.
So your code could look something like this:
string response = null;
using(var tcpc = new TcpClient())
{
tcpc.NoDelay = true;
tcpc.ExclusiveAddressUse = false;
tcpc.Connect("172.18.10.100", 4004);
using (var stream = tcpc.GetStream())
using (var sr = new StreamReader(stream, Encoding.ASCII))
{
sr.Peek();
var Message = "IX3543543" + '\r';
stream.Write(Encoding.ASCII.GetBytes(Message), 0, Message.Length);
response = sr.ReadToEnd();
}
}
// examine message here
var lines = response.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
i have trouble with the following two functions. Both have a indentical basic scheme but first one work, second one causes an exception at marked line("File is used by another process").
// this works
public static void EncryptFile(string FileName)
{
string ToEncrypt = null;
using(StreamReader sr = new StreamReader(FileName))
{
ToEncrypt = sr.ReadToEnd();
}
using(StreamWriter sw = new StreamWriter(FileName, false))
{
string Encrypted = Encrypt(ToEncrypt, true);
sw.Write(Encrypted);
}
}
// this works not - see commented lin
public static void DecryptFile(string FileName)
{
string ToDecrypt = null;
using (StreamReader sr = new StreamReader(FileName))
{
ToDecrypt = sr.ReadToEnd();
}
// here comes the exception
using (StreamWriter sw = new StreamWriter(FileName, false))
{
string Decrypted = Decrypt(ToDecrypt, true);
sw.Write(Decrypted);
}
}
I have tried with an additional Close() after read and write, but this works not too.
I hope, somebody can help.
Thanks
Torsten
Is the function called from multiple threads? If yes you may want to declare a static object on class level and place a lock statement around the entire body of that method. Like this:
private static Object syncObject = new Object()
// this works not - see commented lin
public static void DecryptFile(string FileName)
{
lock(syncObject)
{
string ToDecrypt = null;
using (StreamReader sr = new StreamReader(FileName))
{
ToDecrypt = sr.ReadToEnd();
}
// here comes the exception
using (StreamWriter sw = new StreamWriter(FileName, false))
{
string Decrypted = Decrypt(ToDecrypt, true);
sw.Write(Decrypted);
}
}
}
Also could you, just for fun, comment the StreamReader statement and try to run the method again? If it still doesn't work, check if you've that file open in a texteditor or something alike by using ProcessExplorer or something similiar.
edit
could you comment the StreamReader part? So that it looks like this:
public static void DecryptFile(string FileName)
{
//string ToDecrypt = null;
//using (StreamReader sr = new StreamReader(FileName))
//{
// ToDecrypt = sr.ReadToEnd();
//}
// here comes the exception
using (StreamWriter sw = new StreamWriter(FileName, false))
{
string Decrypted = Decrypt(ToDecrypt, true);
sw.Write(Decrypted);
}
}
also could you try to open an exclusive FileStream on that file before the StreamReader and once after the StreamReader but before the StreamWriter? http://msdn.microsoft.com/de-de/library/tyhc0kft%28v=vs.110%29.aspx
Also could you try and use another file for that method?
Im working on a little ATM program and I'm stuck on a StreamWritter problem.
On load, my program must use a StreamReader to read in 4 .txt files all located in my bin/debug. Then the user is asked to either Deposit or Withdraw money from the bank accounts located in the .txt files. Everything works fine for the StreamReader which loads all the bank accounts on program loading and for the StreamWriter to write the changes in the .txt files when I add/remove money.
My problem is when I close the program, the loading of the files works just fine but I can't write in the files anymore. My StreamWriter jumps straight to the Catch part and cannot be instantiated. How is that possible if it worked just fine on first use.
Heres the StreamReader Code :
public bool ReadSavingAccount()
{
string strLine;
string[] strArray;
char[] charArray = new char[] { ',' };
FileStream aFile;
StreamReader sr;
try
{
aFile = new FileStream("mySavingAccount.txt", FileMode.Open);
sr = new StreamReader(aFile);
strLine = sr.ReadLine();
while (strLine != null)
{
strArray = strLine.Split(charArray);
Savings monSave = new Savings(strArray[0], Convert.ToDouble(strArray[1]));
mySavingAccount.Add(monSave);
strLine = sr.ReadLine();
}
sr.Close();
aFile.Close();
}
catch
{
return false;
}
return true;
}
And the StreamWrite Code:
public bool WriteSavingAccount()
{
FileStream aFile;
StreamWriter sw;
string myString;
try
{
aFile = new FileStream("mySavingAccount.txt", FileMode.Create);
sw = new StreamWriter(aFile);
}
catch
{
return false;
}
foreach (Savings mySave in mySavingAccount)
{
myString = mySave.AccountNumber + "," + mySave.AccountBalance;
sw.WriteLine(myString);
}
sw.Close();
return true;
}
Any idea what the problem could be ?
Thanks in advance and let me know if you need any other parts of the code.
Try adding a second parameter of boolean to your StreamWriter call. This is the append parameter. True to append to the file, false to overwrite it.
sw = new StreamWriter(aFile, false);
Create your StreamWriter in a using statement to ensure it is closed properly.