经测试,两台工控机之间局域网通信正常,如下图:
通过连接客户端的不同开启各自客户端的服务线程,服务器端选取不同客户端也可以通过该服务线程发送消息给客户端。实现代码如下:
复制
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Net; using System.Net.Sockets; using System.Threading; namespace server { public partial class Form1 : Form { public delegate void updata (String arg,int i); Socket mysocket = null; Dictionary<String, Socket> mydic = new Dictionary<string, Socket> (); Dictionary<String, Thread> mythread = new Dictionary<string, Thread> (); public Form1 () { InitializeComponent (); } private void Form1_Load ( object sender, EventArgs e ) { comboBox1.Items.Add ( "等待连接" ); comboBox1.SelectedIndex = comboBox1.Items.IndexOf ( "等待连接" ); String ipadress = "127.0.0.1"; int prots = 3344; mysocket = new Socket (AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp); IPAddress ipsa = IPAddress.Parse (ipadress); IPEndPoint ipenp = new IPEndPoint (ipsa,prots); mysocket.Bind (ipenp); mysocket.Listen (10); Thread thread1 = new Thread (new ThreadStart(waitconnet)); thread1.IsBackground = true; thread1.Start (); } public void waitconnet () { updata ipda = new updata (updataui); while(true){ Socket socketconn = mysocket.Accept (); mydic.Add (socketconn.RemoteEndPoint.ToString(),socketconn); Invoke (ipda,socketconn.RemoteEndPoint.ToString(),1); ParameterizedThreadStart pts = new ParameterizedThreadStart(mesgthread); Thread threadmes = new Thread (pts); threadmes.IsBackground = true; threadmes.Start (socketconn); mythread.Add (socketconn.RemoteEndPoint.ToString(),threadmes); } } public void mesgthread (object socketpra) { updata upd = new updata (updataui); int ststics = 0; Socket socketrec = socketpra as Socket; while(true){ byte[] argmesg = new byte[1024 * 1024]; int length = -1; try { length = socketrec.Receive (argmesg); String getstr = Encoding.UTF8.GetString (argmesg,0,length); Invoke (upd,getstr,0); } catch(Exception ex) { if (ststics==0) { mydic.Remove (socketrec.RemoteEndPoint.ToString ()); mythread.Remove (socketrec.RemoteEndPoint.ToString()); Invoke (upd,socketrec.RemoteEndPoint.ToString(),2); Invoke ( upd, socketrec.RemoteEndPoint.ToString ()+ex.ToString(), 0 ); } ststics = 1; } Thread.Sleep (100); } } public void updataui (String arg,int i) { if(i==0){ textBox2.Text += arg; } else if (i == 1) { comboBox1.Items.Add (arg); comboBox1.SelectedIndex = comboBox1.Items.IndexOf ( arg ); } else if (i == 2) { comboBox1.Items.Remove (arg); if (comboBox1.Items.Count < 1) { comboBox1.Items.Add ( "等待连接" ); comboBox1.SelectedIndex = comboBox1.Items.IndexOf ( "等待连接" ); } else { String keys = comboBox1.Items[comboBox1.Items.Count-1].ToString (); comboBox1.SelectedIndex = comboBox1.Items.IndexOf ( keys ); } // comboBox1.Items.Remove (arg); // comboBox1.SelectedIndex=1; } } private void button1_Click ( object sender, EventArgs e ) { byte[] strmes = Encoding.UTF8.GetBytes (textBox1.Text.ToString()); String clent = comboBox1.Text; mydic[clent].Send (strmes); textBox2.Text += textBox1.Text; textBox1.Text = ""; } } }
线程与UI之间不能直接操作,需要使用委托来实现,服务器接收到客户端的消息也需要通过注册事件来回调主线程更新UI。
委托与事件在C#里是非常重要的,不然很多效果实现不了,还有线程也很重要!
下面附上源码,编译环境是.net4.5,vs2012中编译通过。
评论 (2)