我正在尝试建立一个聊天,基本上我使用了调用函数一个线程
我能够读取服务器发送给我的内容,但我只能写一次。我想完成这个但不确定每次服务器如何写入服务器:
(考虑到我之前在控制台申请表中写了这个,服务器工作正常......即问题不在于服务器)。
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 TcpClient("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();
}
}
我想要做的是连接按钮,这样它就可以进行多次点击..例如btn.Click()..或者在WriteLine上运行一个带调用的线程(但是我的直觉说制作按钮点击几次会使程序正常工作
答案 0 :(得分:1)
您需要在关闭表单时停止线程进程,如果不是在尝试执行调用时,它将失败,因为表单已被释放且无法用于执行调用。您可以覆盖dispose方法以停止reader线程,也可以在onclose方法上执行此操作。或者你可以查看阅读器进程是否有可用的控件(它没有被处理)以及它是否可用完成阅读过程。
您应该防止读者进程多次启动,以防止错误,因此您需要在线程运行时禁用该按钮。
编辑:
您可以使用类似以下代码的内容来读取多行并在关闭表单时停止该行。
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));
}
}
答案 1 :(得分:0)
运行你的代码,我得到了一堆错误 - 来自TcpClient抛出异常等等。 但是,假设您没有发布所有代码,我建议您尝试使用try ...捕获所有函数,然后在catch中查找断点以查看问题所在。检查异常 - 异常只应在特殊情况下抛出 - 因此您的代码应该在不执行此操作的情况下正常工作。
答案 2 :(得分:0)
我在服务器代码上结束:
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"); }
}
}