I am trying to build a chat, basically i used the invoke function what a thread.
I am able to read what the server sends me, but i am able to write only once. i am trying to finish this but not sure how to write to server each time the server: (take into account that i wrote this before in console application form and the server works fine... i.e. the problem isnt with the server).public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
Button btn1 = new Button();
btn1.Click += button1_Click;
}
StreamReader sr;
StreamWriter sw;
TcpClient connection;
private void Form1_Load(object sender, EventArgs e)
{
connection = new Tcp开发者_如何学CClient("127.0.0.1", 5000);
sr = new StreamReader(connection.GetStream());
sw = new StreamWriter(connection.GetStream());
}
private void button2_Click(object sender, EventArgs e)
{
Thread t2 = new Thread(Reader);
t2.Start(connection);
}
string msg;
public void Reader(object o)
{
TcpClient con = o as TcpClient;
if (con == null)
return;
while (true)
{
msg = sr.ReadLine();
Invoke(new Action(Output));
}
}
public void Output()
{
ChatScreen.Text = msg;//set the message on the screen
}
string textinput;
private void button1_Click(object sender, EventArgs e)
{
textinput = InputLine.Text;
sw.WriteLine(textinput);// this thing, writes once, multiple clicks wont send a new line to the server :(..the problem is in this button
sw.Flush();
}
}
what I thought to do is to connect the button so it will be able to do multiple clicks ..e.g btn.Click()..or run a thread with invoke on the WriteLine (but my intuition says that making the button click several times would make the program work
You need to stop the thread process when you close the form, if not when you try to do the invoke, it will fail because the form is disposed and it can't be used to do an invoke. You can override the dispose method to stop the reader thread or you can do it on the onclose method. Or you can check on the reader process if the control it's available (it is not disposed) and if it's not available finish the read process.
You should prevent that the reader process will be launch multiple times too, to prevent errors, so you need to disable the button when the thread is run.
Edited:
You can use something like the following code to read multiple lines and to stop the thread when you close the form.
private bool mbIsRunning = true;
private void Form1_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
lock (this)
{
mbIsRunning= false;
}
}
private bool IsRunning
{
get
{
lock(this)
{
return mbIsRunning;
}
}
}
string msg;
public void Reader(object o)
{
TcpClient con = o as TcpClient;
if (con == null)
return;
while (IsRunning)
{
msg = reader.ReadLine();
string line;
while( (line = reader.ReadLine()) != null )
{
msg = msg + Enviroment.NewLine + line;
}
Invoke(new Action(Output));
}
}
Running up your code, I get a bunch of errors - from the TcpClient throwing an exception and so on. However, assuming that you haven't posted all of your code, I would recommend putting a try...catch around all of your functions, and then breakpoints in the catch to see what the problem is. Examine the exceptions - exceptions should only be thrown in exceptional circumstances - so your code should really work without doing that.
I do concat on my server code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Threading;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
TcpListener server = new TcpListener(IPAddress.Any, 5000);
server.Start();
Console.WriteLine("Server started");
string word = "";
savedObject saved = new savedObject();
while (true)
{
TcpClient connection = server.AcceptTcpClient();
Console.WriteLine("connection accepted");
ThreadPool.QueueUserWorkItem(saved.ProssecClient, connection);
}
}
}
}
class savedObject
{
Dictionary<string, StreamWriter> dic = new Dictionary<string, StreamWriter>();
StreamReader[] sr1 = new StreamReader[100];
StreamWriter[] sw1 = new StreamWriter[100];
string[] name = new string[100];
int m;
int a;
int g;
string word;
public string AllWords(string sit)
{
word += sit + " ";// here i concat them
return word;
}
public string word2()
{
return word;
}
public void ProssecClient(object o)
{
TcpClient connection = o as TcpClient;
if (connection == null)
{
return;
}
StreamReader sr = new StreamReader(connection.GetStream());
StreamWriter sw = new StreamWriter(connection.GetStream());
sr1[a++] = new StreamReader(connection.GetStream());
sw1[m++] = new StreamWriter(connection.GetStream());
string word2 = "";
sw.WriteLine("Please, fill your name: ");
name[g++] = sr.ReadLine();
if (name[g] != null && sw1[m] != null)
{
dic.Add(name[g], sw1[m]);
}
try
{
while (true)
{
int i = 0;
word2 = AllWords(sr.ReadLine());
for (i = 0; i < 3; i++)
{
if (sw1[i] != null)
{
sw1[i].WriteLine( name[i] + ": " + word2);// here is the words that are sent..
sw1[i].Flush();
}
}
}
}
catch { Console.WriteLine("client left"); }
}
}
精彩评论