ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2021-07-27 12:33:45  阅读:219  来源: 互联网

标签:socketWatch Text void private new 服务器 Sockets 客户端


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

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

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

 

第一部分  窗体设计

1.服务器端

                                  

2.客户端

                                   

 

第二部分  代码

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

 

标签:socketWatch,Text,void,private,new,服务器,Sockets,客户端
来源: https://blog.csdn.net/qq_37384437/article/details/119140670

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有