Sockets实现服务器与多个客户端进行通讯

原文链接:https://blog.csdn.net/ba_wang_mao/article/details/107269745

        对于Sockets的学习,可先看一下文档:  

        http://blog.csdn.net/hulihui/article/details/3230503#st      点击打开链接        PS: /*附有源码*/

 

第一部分  窗体设计

1.服务器端

                                  Sockets实现服务器与多个客户端进行通讯

2.客户端

                                   Sockets实现服务器与多个客户端进行通讯

 

第二部分  代码

1.服务器端:

– 申请一个socket (socketWatch)用来监听的
– 绑定到一个IP地址和一个端口上
– 开启侦听,等待接授客户端的连接
– 当有连接时创建一个用于和连接进来的客户端进行通信的socket(socketConnection)
– 即续监听,等侍下一个客户的连接

//服务器端
using System.IO;
using System.Net;
using System.Threading;
using System.Net.Sockets;
 
 
namespace SocketsServer
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
 
        Socket socketWatch = null;
        Thread threadWatch = null;
 
 
        private void startconn_Click(object sender, EventArgs e)
        {
            socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            IPAddress ipaddress = IPAddress.Parse(localip.Text.Trim());
            IPEndPoint endpoint = new IPEndPoint(ipaddress, int.Parse(porttext.Text.Trim()));
            socketWatch.Bind(endpoint);
 
            socketWatch.Listen(10);
            threadWatch = new Thread(WatchingConn);
            threadWatch.IsBackground = true;
            threadWatch.Start();
 
            this.Invoke(new Action(() =>
            {
                recmsg.AppendText("开始对客户端进行监听!" + "\r\n");
            }
                ));
        }
 
  
        //保存了服务器端所有负责和客户端通信发套接字
        Dictionary<string, Socket> dictSocket = new Dictionary<string, Socket>();
        //保存了服务器端所有负责调用通信套接字.Receive方法的线程
        Dictionary<string, Thread> dictThread = new Dictionary<string, Thread>();
 
        //Socket socConn = null;
 
        private void WatchingConn(object obj)
        {
            while (true)
            {
                Socket socConn = socketWatch.Accept();
 
                this.Invoke(new Action(() => {
                    //向下拉项中添加一个客户端的ip端口字符串,作为客户端的唯一标识
                    iptext.Items.Add(socConn.RemoteEndPoint.ToString());
                }));
 
        
                将与客户端通信的套接字对象sokConn添加到键值对集合中,并以客户端IP端口作为键
                dictSocket.Add(socConn.RemoteEndPoint.ToString(), socConn);
  
                ParameterizedThreadStart pts = new ParameterizedThreadStart(RecMsg);
 
                Thread trd = new Thread(pts);
                trd.IsBackground = true;
                trd.Start(socConn);
 
                dictThread.Add(socConn.RemoteEndPoint.ToString(), trd);
                this.Invoke(new Action(()=>
                    {
                        recmsg.AppendText("客户端连接成功!" + "\r\n");
                    }
                    ));
            }
        }
 
 
 
        private void RecMsg(object socketClientPara)
        {
            Socket socketRec = socketClientPara as Socket;
 
            while (true)
            {
                byte[] arrRecMsg = new byte[1024 * 1024];
 
                //int length = socketClient.Receive(arrRecMsg);//......wrong...... 
                int length = -1;
                try
                {
                    length = socketRec.Receive(arrRecMsg);
                }
                catch (SocketException ex)
                {
                    MessageBox.Show("异常:" + ex.Message);
                    //从通信套接字集合中删除被中断连接的通信套接字对象
                    dictSocket.Remove(socketRec.RemoteEndPoint.ToString());
                    //从通信线程结合中删除被终端连接的通信线程对象
                    dictThread.Remove(socketRec.RemoteEndPoint.ToString());
                    //从列表中移除被中断的连接 ip:Port
                    iptext.Items.Remove(socketRec.RemoteEndPoint.ToString());
                    break;
                }
                catch (Exception ex)
                {
                    MessageBox.Show("异常:" + ex.Message);
                    break;
                }
 
                string str = Encoding.UTF8.GetString(arrRecMsg, 0, length);
                this.Invoke(new Action(() => {
                    recmsg.AppendText(iptext.Text + ":\r\n" + GetTime() + "\r\n" + str + "\r\n");
 
                }));
 
                Thread.Sleep(10);
            }
        }
 
 
 
        private DateTime GetTime()
        {
 
            DateTime getTime = new DateTime();
            getTime = DateTime.Now;
            return getTime;
        }
 
 
        private void SendMsg(string sendMsg)
        {
            if (string.IsNullOrEmpty(iptext.Text))
            {
                MessageBox.Show("请选择通信IP!");
            }
            else
            {
                byte[] strSendMsg = Encoding.UTF8.GetBytes(sendMsg);
                string strClientKey = iptext.Text;//通过Key匹配对应ip地址的客户端
                dictSocket[strClientKey].Send(strSendMsg);
                this.Invoke(new Action(() =>
                {
                    recmsg.AppendText("服务器:" + "\r\n" + GetTime() + "\r\n" + sendMsg + "\r\n");
 
                }));
 
                sendmsg.Text = null;
            }
        }
 
 
 
        private void sendok_Click(object sender, EventArgs e)
        {
            SendMsg(sendmsg.Text.Trim());
        }
    }
}

2.客户端:

– 申请一个socket
– 连接服务器(指明IP地址和端口号)

//客户端
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Threading;
 
 
namespace SocketsClient
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
 
 
        Socket socketWatch = null;
        Thread threadWatch = null;
 
 
        private void startconn_Click(object sender, EventArgs e)
        {
            socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            IPAddress address = IPAddress.Parse(iptext.Text.Trim());
            IPEndPoint endpoint = new IPEndPoint(address, int.Parse(porttext.Text.Trim()));
 
            socketWatch.Connect(endpoint);
           // socketWatch.Bind(endpoint);//...报错(服务器是Bind,客户端是Connect)...
            threadWatch = new Thread(RecMsg);
            threadWatch.IsBackground = true;
            threadWatch.Start();
        }
 
 
 
        private void RecMsg(object obj)
        {
            while (true)
            {
                byte[] arrRecMsg = new byte[1024 * 1024];
                int length = socketWatch.Receive(arrRecMsg);
                string str = Encoding.UTF8.GetString(arrRecMsg, 0, length);
                this.Invoke(new Action(() => {
                    recmsg.AppendText("服务器:" + "\r\n" + GetTime() + "\r\n" + str + "\r\n");
 
                }));
            }
        }
 
 
 
        private DateTime GetTime()
        {
            DateTime getTime = new DateTime();
            getTime = DateTime.Now;
            return getTime;
        }
 
 
        private void SendMsg(string sendMsg)
        {
            byte[] strSenMsg = Encoding.UTF8.GetBytes(sendMsg);
            socketWatch.Send(strSenMsg); 
 
            this.Invoke(new Action(() =>
            {
                recmsg.AppendText("客户端:" + "\r\n" + GetTime() + "\r\n" + sendMsg + "\r\n");
 
            }));
 
            sendmsg.Text = null;
        }
 
 
        private void sendok_Click(object sender, EventArgs e)
        {
            SendMsg(sendmsg.Text.Trim());
        }
    }
}

下载路径:下载链接
 

————————————————
版权声明:本文为CSDN博主「勤劳的小码农」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u011602967/article/details/50728443

https://blog.csdn.net/u011602967/article/details/50728443

 

上一篇:c#使用websocket


下一篇:Java培训实战教程之angularJS的双向数据绑定