一、Server 部分
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net.Sockets;
using System.Net;
using System.Threading;
using System.IO;
namespace WindowsFormsApplication1
{
public partial class frm_Main : Form
{
public frm_Main()
{
InitializeComponent();
}
TcpListener listener;
private bool bIsExit = false;
private void Form1_Load(object sender, EventArgs e)
{
}
///
/// 监听RTU连接
///
private void ListenClientConnect()
{
TcpClient Client=null;
while (!bIsExit)
{
try
{
Client= listener.AcceptTcpClient();
}
catch(Exception e)
{
break;
}
RTUClient newRTUClient = new RTUClient(Client);
Thread threadReceive = new Thread(ReceiveData);
threadReceive.Start(newRTUClient);
// Save the RTU into the list
GlobalClass.listRTUClient.Add(newRTUClient);
}
}
delegate void ShowMessageDelegate(string message);
private void ShowMessage(string message)
{
if (listBox1.InvokeRequired)
{
ShowMessageDelegate dShowMessage = ShowMessage;
listBox1.Invoke(dShowMessage, new object[] { message });
}
else
{
listBox1.Items.Insert(0, DateTime.Now.ToString() + ":" + message);
}
}
///
/// 处理接收的RTU信息
///
/// RTU
private void ReceiveData(object Client)
{
RTUClient rtuClient = (RTUClient)Client;
TcpClient client = rtuClient.client;
while (!bIsExit)
{
string strMessage;
try
{
strMessage = rtuClient.br.ReadString();
}
catch (Exception ex)
{
break;
}
ShowMessage(strMessage);
}
}
private void button1_Click(object sender, EventArgs e)
{
try
{
listener = new TcpListener(IPAddress.Parse("127.0.0.1"), 8999);
listener.Start();
ShowMessageDelegate dShowMessage = ShowMessage;
if (listBox1.InvokeRequired)
{
listBox1.Invoke(dShowMessage, new object[] { "服务开启成功!" });
}
else
{
listBox1.Items.Insert(0, "服务开启成功!" + Environment.NewLine);
}
Thread tListenClientConnect = new Thread(ListenClientConnect);
tListenClientConnect.Start();
}
catch (Exception ex)
{
FileStream fs = new FileStream("SystemLog.txt", FileMode.Create, FileAccess.Write);
StreamWriter sw = new StreamWriter(fs);
sw.BaseStream.Seek(0, SeekOrigin.Begin);
sw.WriteLine(ex);
sw.Close();
}
}
private void button2_Click(object sender, EventArgs e)
{
}
private void richTextBox1_TextChanged(object sender, EventArgs e)
{
}
private void button3_Click(object sender, EventArgs e)
{
GlobalClass.listRTUClient[0].bw.Write(richTextBox1.Text.ToString().Trim());
}
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
}
private void frm_Main_FormClosing(object sender, FormClosingEventArgs e)
{
bIsExit = true;
for (int i = GlobalClass.listRTUClient.Count-1; i>=0; i--)
{
GlobalClass.listRTUClient.Remove(GlobalClass.listRTUClient[i]);
if (GlobalClass.listRTUClient[i] != null)
{
GlobalClass.listRTUClient[i].Close();
}
}
}
}
}
二、Client部分
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net.Sockets;
using System.Net;
using System.Threading;
namespace RTU_TestClient
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
RTUClient rtuClient;
private bool bIsExit=false;
private void button1_Click(object sender, EventArgs e)
{
TcpClient client = new TcpClient();
try
{
client.Connect(IPAddress.Parse("127.0.0.1"), 8999);
ShowMessage("Connect Successful!"+Environment.NewLine);
}
catch (Exception ex)
{
return;
}
rtuClient = new RTUClient(client);
Thread threadReceive = new Thread(ReceiveData);
threadReceive.Start(rtuClient);
}
///
/// 处理接收的RTU信息
///
/// RTU
private void ReceiveData(object Client)
{
RTUClient rtuClient = (RTUClient)Client;
TcpClient client = rtuClient.client;
while (!bIsExit)
{
string strMessage;
try
{
strMessage = rtuClient.br.ReadString();
}
catch (Exception ex)
{
break;
}
ShowMessage(strMessage);
}
}
///
/// Show message
///
///
delegate void ShowMessageDelegate(string message);
private void ShowMessage(string message)
{
if (listBox1.InvokeRequired)
{
ShowMessageDelegate dShowMessage = ShowMessage;
listBox1.Invoke(dShowMessage, new object[] { message });
}
else
{
listBox1.Items.Insert(0, DateTime.Now.ToString() + ":" + message);
}
}
private void button3_Click(object sender, EventArgs e)
{
string str_Message = richTextBox1.Text.ToString().Trim();
rtuClient.bw.Write(str_Message);
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
bIsExit = true;
if (rtuClient != null)
{
rtuClient.Close();
}
}
}
}
三、所设计的Client类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.IO;
namespace WindowsFormsApplication1
{
///
/// RTU Class
///
class RTUClient
{
public TcpClient client;
public BinaryReader br;
public BinaryWriter bw;
///
/// RTU 构造方法
///
///
public RTUClient(TcpClient client)
{
this.client = client;
NetworkStream networkStream = client.GetStream();
br = new BinaryReader(networkStream);
bw = new BinaryWriter(networkStream);
}
///
/// RTU Close function
///
public void Close()
{
br.Close();
bw.Close();
client.Close();
}
}
}
四、总结
第一点,线程调用控件设计,采用委托方法进行设计
delegate void ShowMessageDelegate(string message);
private void ShowMessage(string message)
{
if (listBox1.InvokeRequired)
{
ShowMessageDelegate dShowMessage = ShowMessage;
listBox1.Invoke(dShowMessage, new object[] { message });
}
else
{
listBox1.Items.Insert(0, DateTime.Now.ToString() + ":" + message);
}
}
第二点,在线程中进行循环时,不要用"true",应该用一个bool变量进行控制,以便于方便退出
第三点,在C#里面进行TCPIP通讯编程时,可以采用两种方式,一种是采用socket方式,也是最底层的方式,可以采用多种协议,第二种则是采用C#已经封装好的
TcpListener和TcpClient类,方便设计。
进行相关读写操作时,可以采用 BinaryReader和BinaryWriter两个操作读写的方法。
public RTUClient(TcpClient client)
{
this.client = client;
NetworkStream networkStream = client.GetStream();
br = new BinaryReader(networkStream);
bw = new BinaryWriter(networkStream);
}