让代码更简单

C#Socket套接字使用Tcp协议通信(服务器端)

重要:本文最后更新于2019-08-05 08:53:18,某些文章具有时效性,若有错误或已失效,请在下方留言或联系代码狗

经测试,两台工控机之间局域网通信正常,如下图:

C#Socket套接字使用Tcp协议通信(服务器端)

C#Sockets通信服务端

通过连接客户端的不同开启各自客户端的服务线程,服务器端选取不同客户端也可以通过该服务线程发送消息给客户端。实现代码如下:

复制
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中编译通过。

客户端代码:C#Socket套接字使用Tcp协议通信(客户端)

感觉很棒!可以赞赏支持我哟~

12 打赏

评论 (2)

登录后评论
如何关闭服务器连接
好的代码都是有很清晰的注释,希望博主加上详细一点的注释
QQ咨询 邮件咨询 狗哥推荐