用Winform实现Socket网络通信

用Winform实现Socket网络通信

一、Socket

​ 概念:通常称作“套接字”,用于描述IP地址和端口,是一个通信链的句柄,可以用来实现不同虚拟机或计算机之间的通信;客户端如果要连接服务器,首先要知道服务器的IP地址,但服务器中有很多应用程序,光知道IP地址是不够的,因为客户端不知道连接哪一个程序,所以还需要知道一个服务器的端口号。有了服务器的IP地址和端口号,才能建立Socket连接。

二、传输过程中要有传输协议:

​ TCP特点:安全稳定,不会发生数据丢失,效率低,要求必须有一个服务器。

​ 经历三次握手过程:1)客户端请求;2)服务器响应;3)客户端得知服务器响应,开始传输。

​ UDP特点:效率高,但有可能会发生数据丢失(不稳定)。不用经过服务器响应是否有空闲接受消息,自主传输。

​ 举例:视频聊天时,TCP肯定会很清晰,但有可能会卡,因为服务器可能会忙;而UDP不会很清晰,但不会卡,所以视频聊天一般使用UDP协议(参考https://blog.csdn.net/tufeiax/article/details/45591917

三、具体实现方式

服务器Sever端:

1)首先创建socket对象负责监听,并获取本机IP地址,再创建端口号对象将IP地址传入进去

Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPAddress ip = IPAddress.Parse(textBox_ip.Text);
IPEndPoint point = new IPEndPoint(ip, Convert.ToInt32(textBox_port.Text));

2)绑定监听,参数为端口号对象point

socket.Bind(point);
label1.Text = "监听服务已启动!";

3)设置监听以及等待队列

socket.Listen(10);

4)设置接收客户端的连接(注意:要写在while(true)循环中,因为要一直监听,并且创建后台新进程来执行,不止一个客户端要连接服务器,要不断创建负责通信的socket对象socketConnect)

        /// <summary>
        /// 接收客户端的连接
        /// </summary>
        public Socket socketConnect;
        private void Listen(object o)
        {
            try
            {
                Socket socket = o as Socket;
                while (true)
                {
                    //负责监听的Socket来接受客户端的连接,创建跟客户端通信的Socket
                    socketConnect = socket.Accept();
                    dicList.Add(socketConnect.RemoteEndPoint.ToString(), socketConnect);
                    listBoxCoustomerList.Items.Add(socketConnect.RemoteEndPoint.ToString());
                    textboMsg.AppendText(socketConnect.RemoteEndPoint.ToString() + " 上线啦\r\n");
                    Thread th = new Thread(Receive);
                    th.IsBackground = true;
                    th.Start(socketConnect);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("客户端连接失败," + ex.Message);
            }
        }

5)接收客户端发来的消息

        /// <summary>
        /// 接收客户端发来的消息
        /// </summary>
        /// <param name="o"></param>
        private void Receive(object o)
        {
            try
            {
                Socket socketReceive = o as Socket;
                while (true)
                {
                    byte[] buffer = new byte[1024 * 1024 * 5];
                    int r = socketReceive.Receive(buffer);
                    if (r == 0)
                    {
                        break;
                    }
                    textboMsg.AppendText(socketReceive.RemoteEndPoint.ToString() + ":" + Encoding.Default.GetString(buffer, 0, r) + "\r\n");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

6)选择一个客户端给其发送信息

        /// <summary>
        /// 给客户端发送消息
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSendMsg_Click(object sender, EventArgs e)
        {
            try
            {
                string SendMess = textBoxSendMsg.Text;
                byte[] buffer = Encoding.Default.GetBytes(SendMess);
                List<byte> sendList = new List<byte>();
                sendList.Add(0);
                sendList.AddRange(buffer);
                byte[] newBuffer = sendList.ToArray();
                string point=null;
                if (listBoxCoustomerList.SelectedItem!= null)
                {
                    point = listBoxCoustomerList.SelectedItem.ToString();
                    dicList[point].Send(newBuffer);
                }
                else
                {
                    MessageBox.Show("请选择一个客户端发消息!!!", "Error");
                } 
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

7)给全部客户端发送消息

        /// <summary>
        /// 给全部客户端发送消息
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnAllSend_Click(object sender, EventArgs e)
        {
            try
            {
                string SendMess = textBoxSendMsg.Text;
                byte[] buffer = Encoding.Default.GetBytes(SendMess);
                List<byte> sendList = new List<byte>();
                sendList.Add(2);
                sendList.AddRange(buffer);
                byte[] newBuffer = sendList.ToArray();
                foreach (var item in listBoxCoustomerList.Items)
                {
                    dicList[item.ToString()].Send(newBuffer);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }        

​ 要是想要给客户端发送图片或者震动等,可以将发送的数据转为字节,然后创建byte的泛型集合,在集合首位添加数字(例如:单独发送信息是0,全部发送是1,发送图片是2,发送抖动是3),再将字节数组传入添加到结合中,然后客户端那边则以穿过的字节首位数字进行辨别

客户端Client

1)创建负责通信的socket,获取要连接的服务器IP和端口号

Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPAddress ip = IPAddress.Parse(textBoxIp.Text);
IPEndPoint point = new IPEndPoint(ip, Convert.ToInt32(textBoxPort.Text));

2)建立连接

socket.Connect(point);

3)接收服务端发来的消息,因为要不停接收消息,所以要写在while循环中,并且要创建后台新的线程来执行

        Thread th = new Thread(ReceiveMess);
        th.IsBackground = true;
        th.Start();



        /// <summary>
        /// 接收服务器发来的消息
        /// </summary>
        /// <param name="o"></param>
        private void ReceiveMess()
        {
            try
            {
                while (true)
                {
                    byte[] buffer = new byte[1024 * 1024 * 5];
                    int r = socket.Receive(buffer);
                    if (r == 0)
                    {
                        break;
                    }
                    if (buffer[0] == 0)
                    {
                        string RMess = Encoding.Default.GetString(buffer, 1, r - 1);
                        textboMsg.AppendText(socket.RemoteEndPoint.ToString() + ":" + RMess + "\r\n");
                    }
                    else if (buffer[0] == 2)
                    {
                        string RMess = Encoding.Default.GetString(buffer, 1, r - 1);
                        textboMsg.AppendText(socket.RemoteEndPoint.ToString() + ":" + RMess + "(此消息为群发消息,请注意查收)\r\n");
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

4)发送消息给服务器

        /// <summary>
        /// 发送消息给服务器
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSendMsg_Click(object sender, EventArgs e)
        {
            byte[] bytes = Encoding.Default.GetBytes(textBoxSendMsg.Text);
            socket.Send(bytes);
        }

一个简易的Socket网络通信就实现了

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Winform中使用Socket实现屏幕共享,可以通过以下步骤实现自动获取IP和端口: 1. 在Winform界面中添加一个按钮或其他触发屏幕共享操作的元素。 2. 在按钮的点击事件中,创建一个Socket对象,并通过Socket类的Bind方法绑定一个本地IP地址和一个随机的可用端口号。 3. 调用Socket对象的Listen方法开始监听。 4. 通过Socket对象的LocalEndPoint属性获取绑定的本地IP和端口号。 5. 将本地IP和端口号显示在Winform界面中的相应文本框或标签中,使用户可以看到自动获取的IP和端口。 6. 创建一个新的线程,在该线程中实现屏幕捕获的功能。可以使用系统自带的屏幕捕获API或第三方库(如SharpDX或OpenCV)来实现屏幕截图。 7. 在屏幕捕获的线程中,使用Socket对象的Accept方法接收远程客户端的连接请求,并建立一个新的Socket连接。 8. 将屏幕截图转换为字节流,并通过新建立的Socket连接将字节流发送给远程客户端。 9. 在Winform界面中显示连接状态和传输信息,例如可以添加一个文本框或标签来显示连接状态和传输时的数据量等信息。 10. 当需要停止屏幕共享时,关闭Socket连接,并释放相关资源。 需要注意的是,在使用Socket进行网络通信时,需要处理异常情况,比如网络连接中断或传输失败等,并进行适当的错误处理和重试操作,保证程序的稳定性和可靠性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值