如果您需要,请输入以下代码:
(SERVER_CODE)
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace Server
{
public partial class Form1 : Form
{
public int Connections = 0;
public int blocks = 0;
public int threads = 0;
public Thread MasterThread;
public TcpListener Master;
public volatile bool Run;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
public void StartMaster()
{
Master = new TcpListener(IPAddress.Any, 1986);
Master.Start();
MasterThread = new Thread(new ThreadStart(RunMaster));
MasterThread.Start();
}
public void RunMaster()
{
threads++;
label6.Text = String.Format("{0}", threads);
while (Run)
{
TcpClient client = Master.AcceptTcpClient();
Connections++;
label4.Text = String.Format("{0}", Connections);
Thread ClientThread = new Thread(new ParameterizedThreadStart(RunClient));
ClientThread.Start(client);
}
Master.Stop();
threads--;
label6.Text = String.Format("{0}", threads);
}
public void RunClient(object tcpClient)
{
TcpClient client = (TcpClient)tcpClient;
byte[] buffer = new byte[4096];
int byteCount = 0;
NetworkStream stream = client.GetStream();
threads++;
label6.Text = String.Format("{0}", threads);
while (Run)
{
try
{
byteCount = stream.Read(buffer, 0, 4096);
}
catch
{
//Connections--;
break;
}
if (byteCount == 0)
{
//Connections--;
break;
}
blocks++;
label5.Text = String.Format("{0}", blocks);
textBox1.AppendText(Encoding.ASCII.GetString(buffer, 0, byteCount) + "\r\n");
}
client.Close();
threads--;
label6.Text = String.Format("{0}", threads);
}
private void button1_Click(object sender, EventArgs e)
{
Run = true;
StartMaster();
}
private void button2_Click(object sender, EventArgs e)
{
Run = false;
}
}
}
(CLIENT_CODE)
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace Client
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 1986);
TcpClient client = new TcpClient();
try
{
client.Connect(endPoint);
}
catch
{
MessageBox.Show("Connect Error");
}
NetworkStream stream = client.GetStream();
byte[] data = Encoding.ASCII.GetBytes(textBox1.Text);
stream.Write(data, 0, data.Length);
stream.Flush();
client.Close();
}
}
}
感谢-你,
特里斯坦!
答案 0 :(得分:2)
好吧,首先,你要用这个来削弱你自己的诊断:
catch
{
//Connections--;
break;
}
为什么在没有任何日志记录等的情况下吞下异常?也许正在抛出异常,你无从知晓。理想情况下,您应该捕获特定的异常,并且当执行捕获异常时至少记录正在发生的事情。
在频谱的另一端,Wireshark应该可以帮助您确定数据是否正在发送。
答案 1 :(得分:1)
我还没有仔细查看过您的代码,但是快速浏览后,您可以从多个线程访问变量而无需正确锁定。像x++;
这样的语句必须读取x
的值,递增它并将其写回。现在,如果你有两个线程这样做,你可能会遇到这种情况:
x = 0
Thread 1 Thread 2
------------------------
Read (0)
Read (0)
Increment (1)
Increment (1)
Write (1)
Write (1)
=> x = 1 instead of 2
如果您需要从多个线程访问变量,除非您确切知道自己在做什么,否则请始终进行同步。例如,创建并使用如下所示的同步对象:
int threads = 0;
object threadSync = new object();
...
lock (threadSync) {
threads++;
}
然后,一次只有一个线程可以访问该变量,并且值正确递增。
编辑:另一个问题是您从与创建它们的线程不同的线程访问可见控件。早期的.NET版本允许这样做,但是新版本没有。如果需要更新状态消息,则需要查看控件的InvokeRequired
属性,如果设置为true,则使用Control.Invoke(...)调用设置属性的方法。