I'm trying to receive large strings over TCP, I tried various methods, but none of them worked as good as this one (which is quite simple actually).
public partial class MyClass : Form
{
Int64 counter;
StreamWriter writer;
StreamReader reader;
public MyClass(object streamIn, object StreamOut)
{
InitializeComponent();
richTextBox1.BackColor = Color.Black;
richTextBox1.ForeColor = Color.Gray;
writer = (StreamWriter)streamIn;
reader = (StreamReader)StreamOut;
}
private void button1_Click(object sender, EventArgs e)
{
JObject o = new JObject();
char[] buffer = new char[1024];
int count = buffer.Length;
o.Add("comando", 15);
o.Add("filename", textBox2.Text);
o.Add("param", textBox3.Text);
writer.Write(o.ToString());
writer.Flush();
richTextBox1.Text = reader.ReadToEnd();
}
}
The problem using this is that I have to close the stream on the other end, in order for this to read. There is any way I can use reader.ReadToEnd() without having to close the stream on the other end after sending and therefore closing the connection between client-server?
Checkout the Basic Example for the network library networkcomms.net which is covered in the Getting Started article. Although this is a console example it allows you to send arbitrary length strings.
Your example looks like it might be a winform application. There is also a WPF chat application example if that is of interest.
Related
How do i read and sort a text file
sorry if this is an easy question I'm new to coding. I've tried many online solution but none seems to fix my problem:
namespace Login_but_it_hopefully_works
{
public partial class Leaderboard : Form
{
string Line = "";
private string filepath1 = #"Compdetails.txt";
FileStream readerStream = new FileStream("Compdetails.txt", FileMode.Open);
string[] content = null;
public Leaderboard()
{
InitializeComponent();
}
public object ListReadFile { get; private set; }
private void bttn_load_Click(object sender, EventArgs e)
{
string[] content = null;
//Read the content
using (StreamReader CompTXT = File.OpenText(filepath1))
{
content = CompTXT.ReadToEnd().Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
//Remove the entries in the file
readerStream.SetLength(0);
}
FileStream writerStream = new FileStream(#"Desktop\Source\text.txt", FileMode.OpenOrCreate);
using (StreamWriter writer = new StreamWriter(writerStream))
{
//Sort the content and write back to the same file
Array.Sort(content);
writer.Write(string.Join(Environment.NewLine, content));
}
}
}
}
The error is:
Additional information: The process cannot access the file
'E:\CS\Login\Login but it hopefully works\bin\Debug\Compdetails.txt'
because it is being used by another process and the line is " using
(StreamReader CompTXT = File.OpenText(filepath3))"
Remove the 2 lines involving readerStream. They are not accomplishing what do you think they are, but they are causing that error. :-) Your next task will be to overwrite the file rather than append to it.
To elaborate on the cause of the error: having that field declared in the class and initialized by opening a stream causes the file to be locked for as long as an instance of the class exists. When you then call the button event method and try to open another stream with another lock on the same file, an exception results.
I am running an ASP 4.5 application. One one of the pages the user must answer several questions and the push the button to finish the test. My application uses a text file to analyze the users answers. If the user does everything quickly the application works fine, but when it takes longer then 20 min for him to finish the test I get an exception
Cannot read from a closed TextReader
I do not understand what's wrong, because I open StreamReader only when the button is pressed. This is a part of my code:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
GlobalVariables.surname = Request.QueryString["surname"];
GlobalVariables.name = Request.QueryString["name"];
GlobalVariables.gender = Request.QueryString["gender"];
GlobalVariables.age = int.Parse(Request.QueryString["age"]);
}
Label1.Width = 700;
Button1.Click += new EventHandler(this.Button1_Click);
}
void Button1_Click(Object sender, EventArgs e)
{
var f0= new FileStream(Server.MapPath("./key.txt"), FileMode.Open, FileAccess.Read);
StreamReader sr = new StreamReader(f0);
//.....
sr.Close();
sr.Dispose();
}
Could somebody help me please?
when it takes longer then 20 mis for him to finish the test I get an exception
That sounds a lot like their session expired. To fix this, I recommend adding some javascript to establish a heartbeat to the web server. The heartbeat will keep the session alive; it doesn't need to do anything other than simply make a request every minute or so, so the server knows you're still there.
In addition to the answer from Joel I would recommend to separate processing the file from reading the file.
List<string> lines = new List<string>();
using (var f0 = new FileStream(Server.MapPath("./key.txt"), FileMode.Open, FileAccess.Read))
{
string line;
using (StreamReader reader = new StreamReader(f0))
{
while ((line = reader.ReadLine()) != null)
{
lines.add(line);
}
}
}
// it would need to be a very big text file to be a memory issue
// do your processing here
f the page is not a post back, you would want to set up the page as it should be viewed the first time. I would also suggest moving the button click even within the if(!Page.IsPostBack) as well as anything that needs to be setup before a post-back. Move your Stream reader to the else... like so if(!Page.IsPostBack) else { stream reader stuff } and remove the button click even in general since the button causes postback.
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
GlobalVariables.surname = Request.QueryString["surname"];
GlobalVariables.name = Request.QueryString["name"];
GlobalVariables.gender = Request.QueryString["gender"];
GlobalVariables.age = int.Parse(Request.QueryString["age"]);
Label1.Width = 700;
}
else
{
DoPostBackStuff();
}
}
private void DoPostBackStuff()
{
var f0= new FileStream(Server.MapPath("./key.txt"), FileMode.Open, FileAccess.Read);
StreamReader sr = new StreamReader(f0);
//.....
sr.Close();
sr.Dispose();
}
So, I finally managed to make a conection but now im trying to pass images over the server.
The code looks like this:
private void Form1_Load(object sender, EventArgs e)
{
//StartConnectionVideo();
Client = new TcpClient();
Client.Connect("10.0.0.3", 456);
//Connect to 127.0.0.1 on port 3700
readingThread = new Thread(new ThreadStart(StartReading));
//Start a new thread to receive images
readingThread.Start();
}
private void StartReading()
{
while (true)
{
MessageBox.Show("D");
NetworkStream stream = Client.GetStream();
BinaryFormatter formatter = new BinaryFormatter();
Image img = Image.FromStream(stream);
MessageBox.Show("D");
//Deserialize the image from the NetworkStream
MessageBox.Show(img.Width.ToString());
pictureBox1.Image = img; //Show the image in the picturebox
}
}
}
the first message box work(directlry after the loop) but on the second its stuck.
it's just hangs on this line
Image img = Image.FromStream(stream);
the server side is this..
Image img=Image.FromFile(#"C:\Users\איתמר\Desktop\air\amumu_0.jpg");
VideoServer a = new VideoServer(img ,this);
a.StartListening();
//a.padre.pictureBox1.Image = img;
a.SendImage(img);
videoserver is a class i wrote... i'll write here the main important code pieces
public void StartListening()
{
// Create the TCP listener object using the IP of the server and the specified port
tlsClient = new TcpListener (IPAddress.Any, 456);
// Start the TCP listener and listen for connections
tlsClient.Start();
// The while loop will check for true in this before checking for connections
ServRunning = true;
thrListener = new Thread(KeepListening);
thrListener.Start();
}
public void SendImage(Image img)
{
for (int i = 0; i < ClientList.Count; i++)
{
TcpClient tempClient = (TcpClient)ClientList[i];
if (tempClient.Connected) //If the client is connected
{
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(tempClient.GetStream(), img);
//Serialize the image to the tempClient NetworkStream
}
else
{
ClientList.Remove(tempClient);
i--;
}
}
i think i've showed the main code... the rest isnt so important because im prettry sure the problem is in this code...
i appriciate any help of you guys im breaking my head over a week :D
You are serializing the image using BinaryFormatter but deserializing it using Image.FromStream. These are two incompatible formats. You must use the same format both times.
As far as I'm aware Image.FromStream is not documented to cope with infinite streams. In fact I'm quite sure it doesn't because by principle it cannot avoid reading two much (except if it were reading byte-wise which is a performance nightmare). Therefore, you can't use Image.FromStream directly.
I'd do this by first converting the image to a byte[] or a MemoryStream. Then I would first write the length of the image data and then the data. A length prefix is a common way of serializing things.
Or, use a higher-level abstraction such as protobuf.
I'm still on my first step on C# and this is my first post/question.
How do I implement Streamreader to Display(output)
Like after clicking the Dataretrieve button I want to retrieve the data located on "D:\Savedata.txt" and display it on the lblDisplay
This is my code, am I missing something?
void DataretrieveClick(object sender, EventArgs e)
{
StreamReader read = File.OpenText("D:\\Savedata.txt");
lblDisplay.Text = "Last Name: " +textBox1.Text.Trim();
read.Close();
}
Something like this should be what you're looking for.
void DataretrieveClick(object sender, EventArgs e)
{
using (StreamReader reader = File.OpenText("D:\\Savedata.txt"))
{
lblDisplay.Text = reader.ReadToEnd();
}
}
When you create an instance of a class that implements interface IDisposable, you should wrap it in a using() statement to make sure the resources for it are freed when you leave the using() scope. Also, you can look over the documentation for StreamReader here which should help you see what's available.
There is very handy static method ReadAllText in File class, which will open a text file, read all lines of the file, and then close the file:
lblDisplay.Text = File.ReadAllText("D:\\Savedata.txt");
Internally this method does exactly what you are trying to implement (creates StreamReader and reads all characters from the current position to the end of the stream):
using (var reader = new StreamReader(path, Encoding.UTF8, true, 0x400, true))
{
return reader.ReadToEnd();
}
You're looking for read.ReadToEnd().
I am sending and receiving data using COM port (serial). I have written the following code. This is actually my first C# project as I am kinda new to it. I am trying to write the received data to the text file on my desktop, the program actually creates the file but writes nothing in it. Similarly, I am able to see the received data on the console but it is not being written to the text file. Any help on what I am doing wrong will be much appreciated.
Thank you. The code is below.
class Program
{
SerialPort p = new SerialPort("COM7", 300, Parity.None, 8, StopBits.One);
string sbuffer = string.Empty;
byte i = 0;
static void Main(string[] args)
{
new Program();
}
Program()
{
string[] names = SerialPort.GetPortNames();
Console.WriteLine("Serial ports:");
foreach (string name in names)
{
Console.WriteLine(name);
}
Console.WriteLine("Using COM7");
p.Open();
string data_ = "$1RB\r";
Console.WriteLine("Writing data: {0}",data_);
p.Write(data_);
p.DataReceived += new SerialDataReceivedEventHandler(p_DataReceived);
Console.ReadKey();
p.Close();
}
void p_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
Thread.Sleep(5);
sbuffer += (sender as SerialPort).ReadExisting();
i++;
if (i > 9)
{
Console.WriteLine(sbuffer);
System.IO.File.WriteAllText(#"C:\Users\myname\Desktop\WriteText.txt", sbuffer);
sbuffer = string.Empty;
}
}
}
}
You could use events, or simply use this method and pass your data string to it. It will simply append to the file as long as it exists, or create a new file if it does not. The data written should be identical to whatever output is appearing in your console screen.
static void WriteOutputToTextFile(string _data)
{
string FolderName = Environment.GetFolderPath(Environment.SpecialFolder.Desktop); //set destination as your desktop
using (StreamWriter SW = new StreamWriter(FolderName + "\\test.txt", true)) //true makes it append to the file instead of overwrite
{
SW.WriteLine(_data);
SW.Close();
}
}
You are opening and overwriting the same file again and again. Use the FileStream (or even better, StreamWriter) class instead, keep the stream open together with the serial port and close it when you're done.
Also, if you transmit text via the serial port, you might want to consider the SerialPort.ReadLine() method that is much easier to use.
Extending #Alan's answer, you can use File.AppendAllText instead of File.WriteAllText which will overwrite the file again and again. So if you receive empty text before you check the file, the file will be overwritten with empty text.