string strMessage = Encoding.UTF8.GetString(message);
MessageBox.Show("Message: " + strMessage);
int numToRemove = Int32.Parse(strMessage);
char head = strMessage[0];
if(head.ToString() == "2")
{
MessageBox.Show("test");
}
此代码正常,但如果我添加
button5.text = "X";
然后,它开始工作的速度非常慢,而#34; X"在显示的按钮上,以及if语句之后的任何内容都不起作用。
这是整个代码:
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Windows.Forms;
namespace TCPSockets {
public partial class Form1 : Form {
/************
* Spremenljivke
*
*
* **********/
// odjemalec/strežnik
TcpClient client = null;
TcpListener listener = null;
IPAddress ip = null;
int port = 1337;
// niti
Thread thClient = null;
Thread thListener = null;
// podatkovni tok
NetworkStream dataStream = null;
string sporocilo = "";
int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9};
public Form1() {
InitializeComponent();
}
/*************
* Strežnik (listener)
*
* ***********/
private void button1_Click(object sender, EventArgs e) {
// IP & port
ip = IPAddress.Parse(textBox1.Text);
port = Convert.ToInt32(textBox2.Text);
// nit => sicer vmesnik blokira, ko kličemo AcceptTcpClient()
thListener = new Thread(new ThreadStart(ListenForConnections));
thListener.IsBackground = true;
thListener.Start();
}
// ListenForConnections posluša na vratih in sprejema nove odjemalce
// Ko odjemalca sprejme, obdela njegovo sporočilo
private void ListenForConnections() {
listener = new TcpListener(ip, port);
listener.Start();
// neskončna zanka, če želimo prejemati več sporočil
// neskončna zanka zato, ker ne moremo vedeti koliko sporočil bomo prejeli
while (true) {
try {
client = listener.AcceptTcpClient(); // ta funkcija blokira nit dokler se odjemalec ne poveže (ne pošlje sporočila)
// pridobivanje sporočila iz podatkovnega toka
dataStream = client.GetStream(); // dobimo podatkovni tok odjemalca in beremo podatke iz njega
byte[] message = new byte[1024];
dataStream.Read(message, 0, message.Length);
dataStream.Close();
string strMessage = Encoding.UTF8.GetString(message);
MessageBox.Show("Strežnik: Dobil sem sporočilo: " + strMessage);
int numToRemove = Int32.Parse(strMessage);
char head = strMessage[0];
if(head.ToString() == "2")
{
button4.Text = "X";
}
/* else if(head.ToString() == "2")
{
button5.Text = "X";
sporocilo = "";
}
*/
}
// obdelovanje izjem => ko ustavljamo strežnik prožimo izjemo
catch (Exception ex) {
thListener.Join(); // enostavno zaključimo nit z .Join() in ne .Abort()!!!
}
}
}
// ustavljanje strežnika
private void button3_Click(object sender, EventArgs e) {
if (client != null && client.Connected) client.Close(); // če imamo povezanega odjemalca, ta klic proži izjemo v while(true)...
listener.Stop(); // če nimamo povezanega odjemalca, ta klic proži izjemo v while(true)...
}
/**********
* Odjemalec (client)
*
* ********/
private void button2_Click(object sender, EventArgs e) {
ip = IPAddress.Parse(textBox1.Text);
port = Convert.ToInt32(textBox2.Text);
// ustvarimo novo povezavo na strežnik v ločeni niti
// kot parameter si pošljemo TcpClient objekt, da celotno povezavo izvedemo v drugi niti
// na tak način bi lahko izvedli več simultanih povezav na isti strežnik (recimo za pošiljanje več datotek hkrati, ali pa tudi za izvedbo DDoS napada)
client = new TcpClient();
thClient = new Thread(new ParameterizedThreadStart(SendPacket));
thClient.IsBackground = true;
thClient.Start(client);
}
// nit za pošiljanje sporočila
private void button4_Click(object sender, EventArgs e)
{
sporocilo = "1";
}
private void SendPacket(object pClient)
{
string message = sporocilo;
// spet try-catch blok, da polovimo napake (recimo strežnik offline)
try
{
client = (TcpClient)pClient; // samo type cast parametra
client.Connect(ip, port); // dejanska povezava s strežnikom
dataStream = client.GetStream(); // pridobivanje podatkovnega toka in pisanje vanj
byte[] strMessage = Encoding.UTF8.GetBytes(message);
dataStream.Write(strMessage, 0, strMessage.Length);
dataStream.Close(); // vedno, VEDNO!!! zapiramo podatkovne toke...
client.Close(); // ...kot tudi zapremo povezavo, ko smo končali
}
// če je bila napaka, jo lahko na uporabniku prijazen način obdelamo
catch (Exception ex)
{
MessageBox.Show("Odjemalec: Pošiljanje ni bilo uspešno!");
}
}
private void button5_Click(object sender, EventArgs e)
{
sporocilo = "2";
}
}
}
答案 0 :(得分:0)
除了我可以对你的编码风格做的几十点(特别是你应该用英文编写代码)之外,你的主要问题是你试图从另一个线程更新GUI对象。我觉得有趣的是你没有看到异常,但你必须去GUI(主)线程来更新GUI对象。
请参阅this answer,了解您应该如何操作。