写了个线程侦听的小程序,运行看起来正常。
可是每过段时间程序就非正常断线,需要重新连接。总是要关闭,再打开才能用。没看到问题出在哪。下面是代码,哪位老师指点一下吧,谢谢。 public static String connstr = "Data Source=server;Initial Catalog= pay;User ID=ss;Password=sss";//;Pooling=False
private IPAddress myIP ;
private IPEndPoint MyServer;
private Socket sock;
private Socket accSock;
private Byte[] sendByte = new Byte[18];
private Byte[] RecByte = new Byte[16];
public static DataSet ReportSet = new DataSet("ReportSet");
public static String CardID = "";
bool canClose = false;//设定主窗口不可关闭
public string oldMessage = "";//前次收到的信息
//要使用Invoke必须要传递一个委托。所以先定义一个委托类。
//这个委托类使用了三个参数,看后面实际初始化委托时的代码就知道每个参数的意义了。
private delegate void DelOutput(string args);//string format, object[] args);
private delegate void DelOutputLable(string id, string times, string amount); //委托的实际执行函数
//在TextBox上输出一行文本。
private void directOutput(string o)//string format, object[] args)
{
textBox2.AppendText(o);
if (checkBox1.Checked)
{
//取得应用程序的可执行文件的路径。
string Patch = Application.StartupPath + @"\" + DateTime.Today.ToString("yyyyMMdd") + ".txt";
File.AppendAllText(Patch, DateTime.Now.ToString() + " " + o , System.Text.Encoding.Default);
}
}
//任何时候你想要输出数据时调用这个函数,而不是调用上面那个。
//这个函数可以根据你的调用是否是跨线程的而进行相应的处理。
public void Output(string arg)//string format, params object[] args)
{
if (this.InvokeRequired) //根据这个标志判断是否需要跨线程
{
//是跨线程调用,则用Invoke的方式,在创建的线程内执行。
DelOutput indirectOutput = new DelOutput(directOutput);
//注意这里是如何初始化参数数组并传入Invoke函数的。
//object[] ps = new object[] {format,args}; this.Invoke(indirectOutput,arg);// ps);
return;
}
else
{
//如果不是跨线程调用,则直接访问。
directOutput(arg);//format, args);
}
}
//委托的实际执行函数
//在TextBox上输出一行文本。
private void directOutputlable(string id, string times, string amount)
{
label2.Text = id;
label3.Text = times;
label4.Text = amount;
if (checkBox1.Checked)
{
//取得应用程序的可执行文件的路径。
string Patch = Application.StartupPath + @"\" + DateTime.Today.ToString("yyyyMMdd") + ".txt";
File.AppendAllText(Patch, DateTime.Now.ToString() + " " + id + "卡消费" + amount + "\r\n", System.Text.Encoding.Default);
}
} public void Outputlable(string id, string times, string amount)//string format, params object[] args)
{
if (this.InvokeRequired) //根据这个标志判断是否需要跨线程
{
DelOutputLable indirectOutput = new DelOutputLable(directOutputlable);
this.Invoke(indirectOutput, id, times, amount);
return;
}
else
{
directOutputlable(id,times,amount);
}
} private void button1_Click(object sender, EventArgs e)
{
try
{
myIP = IPAddress.Parse(textBox1.Text);
}
catch
{
MessageBox.Show("您输入的IP地址格式不正确,请重新输入!");
return;
}
SqlConnection conn = new SqlConnection(connstr);//;Pooling=False
try
{
//打开连接
if (conn.State == ConnectionState.Closed)
{
conn.Open();
}
}
catch
{
MessageBox.Show("数据库连接失败!");
return;
}
finally
{
//使用结束后关闭数据源连接
if (conn.State == ConnectionState.Open)
{
conn.Close();//断开连接用语句
}
}
StartListeningA();
} //开始同步监听
public void StartListeningA()
{
try
{
Thread thread = new Thread (new ThreadStart(accp));
thread.IsBackground = true;
thread.Start();
}
catch(Exception ee) {MessageBox.Show(ee.Message);}
}
//线程同步方法 accp的代码。
private void accp()
{
MyServer = new IPEndPoint(myIP, 2003);
try
{
sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
sock.Bind(MyServer);
sock.Listen(50);
//MessageBox.Show("开始监听");
while (true)
{
try
{
//textBox2.AppendText("开始监听...\r\n");//textBox2.AppendText("监听停止!\r\n");
accSock = sock.Accept();
if (accSock.Connected)
{
//textBox2.AppendText("设备已连接。");
//MessageBox.Show("设备已连接");
Thread thread = new Thread(new ThreadStart(round));
thread.Start();
thread.IsBackground = true;
Output("设备" + ((IPEndPoint)accSock.RemoteEndPoint).Address.ToString() + "已连接上\r\n");
}
}
catch
{
Output("设备意外关闭");
return;
}
}
}
catch (Exception ee)
{
MessageBox.Show(ee.Message);
return;
}
}
private void round()
{
while (true)
{
NetworkStream netStream = new NetworkStream(accSock);
netStream.Read(RecByte, 0, RecByte.Length);
DO(netStream);
}
}
//关闭系统
private void button3_Click(object sender, EventArgs e)
{
canClose = true;
this.Close();
} private void Form1_Shown(object sender, EventArgs e)
{
textBox1.Text = IPstr();
MakeAmountTable();
MakeCardTable();
} private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (canClose == false)
{
e.Cancel = true;
this.Hide();
notifyIcon1.BalloonTipText = "程序运行中";//"提示内容 ";
notifyIcon1.BalloonTipTitle = "提示:";//"提示标题 ";
notifyIcon1.ShowBalloonTip(1000);
}
}
private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e)
{
this.Show();
} private void toolStripMenuItem1_Click(object sender, EventArgs e)
{
this.Show();
} private void toolStripMenuItem2_Click(object sender, EventArgs e)
{
canClose = true;
this.Close();
}
可是每过段时间程序就非正常断线,需要重新连接。总是要关闭,再打开才能用。没看到问题出在哪。下面是代码,哪位老师指点一下吧,谢谢。 public static String connstr = "Data Source=server;Initial Catalog= pay;User ID=ss;Password=sss";//;Pooling=False
private IPAddress myIP ;
private IPEndPoint MyServer;
private Socket sock;
private Socket accSock;
private Byte[] sendByte = new Byte[18];
private Byte[] RecByte = new Byte[16];
public static DataSet ReportSet = new DataSet("ReportSet");
public static String CardID = "";
bool canClose = false;//设定主窗口不可关闭
public string oldMessage = "";//前次收到的信息
//要使用Invoke必须要传递一个委托。所以先定义一个委托类。
//这个委托类使用了三个参数,看后面实际初始化委托时的代码就知道每个参数的意义了。
private delegate void DelOutput(string args);//string format, object[] args);
private delegate void DelOutputLable(string id, string times, string amount); //委托的实际执行函数
//在TextBox上输出一行文本。
private void directOutput(string o)//string format, object[] args)
{
textBox2.AppendText(o);
if (checkBox1.Checked)
{
//取得应用程序的可执行文件的路径。
string Patch = Application.StartupPath + @"\" + DateTime.Today.ToString("yyyyMMdd") + ".txt";
File.AppendAllText(Patch, DateTime.Now.ToString() + " " + o , System.Text.Encoding.Default);
}
}
//任何时候你想要输出数据时调用这个函数,而不是调用上面那个。
//这个函数可以根据你的调用是否是跨线程的而进行相应的处理。
public void Output(string arg)//string format, params object[] args)
{
if (this.InvokeRequired) //根据这个标志判断是否需要跨线程
{
//是跨线程调用,则用Invoke的方式,在创建的线程内执行。
DelOutput indirectOutput = new DelOutput(directOutput);
//注意这里是如何初始化参数数组并传入Invoke函数的。
//object[] ps = new object[] {format,args}; this.Invoke(indirectOutput,arg);// ps);
return;
}
else
{
//如果不是跨线程调用,则直接访问。
directOutput(arg);//format, args);
}
}
//委托的实际执行函数
//在TextBox上输出一行文本。
private void directOutputlable(string id, string times, string amount)
{
label2.Text = id;
label3.Text = times;
label4.Text = amount;
if (checkBox1.Checked)
{
//取得应用程序的可执行文件的路径。
string Patch = Application.StartupPath + @"\" + DateTime.Today.ToString("yyyyMMdd") + ".txt";
File.AppendAllText(Patch, DateTime.Now.ToString() + " " + id + "卡消费" + amount + "\r\n", System.Text.Encoding.Default);
}
} public void Outputlable(string id, string times, string amount)//string format, params object[] args)
{
if (this.InvokeRequired) //根据这个标志判断是否需要跨线程
{
DelOutputLable indirectOutput = new DelOutputLable(directOutputlable);
this.Invoke(indirectOutput, id, times, amount);
return;
}
else
{
directOutputlable(id,times,amount);
}
} private void button1_Click(object sender, EventArgs e)
{
try
{
myIP = IPAddress.Parse(textBox1.Text);
}
catch
{
MessageBox.Show("您输入的IP地址格式不正确,请重新输入!");
return;
}
SqlConnection conn = new SqlConnection(connstr);//;Pooling=False
try
{
//打开连接
if (conn.State == ConnectionState.Closed)
{
conn.Open();
}
}
catch
{
MessageBox.Show("数据库连接失败!");
return;
}
finally
{
//使用结束后关闭数据源连接
if (conn.State == ConnectionState.Open)
{
conn.Close();//断开连接用语句
}
}
StartListeningA();
} //开始同步监听
public void StartListeningA()
{
try
{
Thread thread = new Thread (new ThreadStart(accp));
thread.IsBackground = true;
thread.Start();
}
catch(Exception ee) {MessageBox.Show(ee.Message);}
}
//线程同步方法 accp的代码。
private void accp()
{
MyServer = new IPEndPoint(myIP, 2003);
try
{
sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
sock.Bind(MyServer);
sock.Listen(50);
//MessageBox.Show("开始监听");
while (true)
{
try
{
//textBox2.AppendText("开始监听...\r\n");//textBox2.AppendText("监听停止!\r\n");
accSock = sock.Accept();
if (accSock.Connected)
{
//textBox2.AppendText("设备已连接。");
//MessageBox.Show("设备已连接");
Thread thread = new Thread(new ThreadStart(round));
thread.Start();
thread.IsBackground = true;
Output("设备" + ((IPEndPoint)accSock.RemoteEndPoint).Address.ToString() + "已连接上\r\n");
}
}
catch
{
Output("设备意外关闭");
return;
}
}
}
catch (Exception ee)
{
MessageBox.Show(ee.Message);
return;
}
}
private void round()
{
while (true)
{
NetworkStream netStream = new NetworkStream(accSock);
netStream.Read(RecByte, 0, RecByte.Length);
DO(netStream);
}
}
//关闭系统
private void button3_Click(object sender, EventArgs e)
{
canClose = true;
this.Close();
} private void Form1_Shown(object sender, EventArgs e)
{
textBox1.Text = IPstr();
MakeAmountTable();
MakeCardTable();
} private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (canClose == false)
{
e.Cancel = true;
this.Hide();
notifyIcon1.BalloonTipText = "程序运行中";//"提示内容 ";
notifyIcon1.BalloonTipTitle = "提示:";//"提示标题 ";
notifyIcon1.ShowBalloonTip(1000);
}
}
private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e)
{
this.Show();
} private void toolStripMenuItem1_Click(object sender, EventArgs e)
{
this.Show();
} private void toolStripMenuItem2_Click(object sender, EventArgs e)
{
canClose = true;
this.Close();
}
//这个句去掉
thread.IsBackground = true;
thread.Start(); 程序中有前能线程,有后台线程,你的前台线程完成后,你的后台线程就会停止,即使没有完成都会停止