ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

C# Socket 实现服务端和客户端通信

2022-08-03 12:03:24  阅读:157  来源: 互联网

标签:socketSend Socket C# System new using 服务端 客户端


C#里面封装好了Socket,直接引用即可使用

关键字:using System.Net; using.System.Sockets;

创建一个负责监听的Socket:Socket socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 第一个参数是IPV42,第二个为流式,TCP用流式,UDP用数式,第三个为协议类型

IP地址获取:IPAddress ip = IPAddress.Any; Any是指当前服务器的所有ip

端口获取:IPEndPoint point = new IPEndPoint(ip, Convert.ToInt32(txtPort.Text));这里获取的文本框里的端口。

将负责监听的Socket绑定IP地址和端口:socketWatch.Bind(point);

设置监听队列,某一时间段最大连接数:socketWatch.Listen(100);

这样一个Socket就创建好了。

下面是接受连接:

    //负责监听的Socket来接收客户端的连接
    while (true)
    {
        //负责跟客户端通信的Socket
        socketSend = socketWatch.Accept();
        //将远程连接的客户端的IP和Socket存入集合中
        dicSocket.Add(socketSend.RemoteEndPoint.ToString(), socketSend);
        //将远程连接的客户端的IP地址和端口号存储到下拉框中
        this.Invoke(new Action(addCbomDic));
                
        //连接成功
        this.Invoke(new Action<string>(ShowMsg), socketSend.RemoteEndPoint.ToString() + "连接成功");
        // ShowMsg(socketSend.RemoteEndPoint.ToString() + "连接成功");

        //接收客户端消息线程
        Task.Run(() => Recive(socketSend));
            
    }

 以上就是Socket部分的主要代码了,下面是服务端的主要实现代码

服务端主要逻辑代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;

namespace MonitorTest
{
    public partial class Form1 : Form
    {
        Socket socketSend;
        //将远程客户端的IP地址和Socket存入集合中
        Dictionary<string, Socket> dicSocket = new Dictionary<string, Socket>();
        public Form1()
        {
            InitializeComponent();
        }

        private void btnsStart_Click(object sender, EventArgs e)
        {
            //创建一个负责监听得Socket
            //第一个参数是IPV42,第二个为流式,TCP用流式,UDP用数式,第三个为协议类型
            Socket socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            //创建IP地址和端口号对象
            IPAddress ip = IPAddress.Any;   //IPAddress.Parse(txtServer.Text);
            IPEndPoint point = new IPEndPoint(ip, Convert.ToInt32(txtPort.Text));

            //让负责监听的Socket绑定IP地址跟端口号
            socketWatch.Bind(point);

            ShowMsg("监听成功");

            //设置监听队列,某一时间点能够连入客户端的最大数量+
            socketWatch.Listen(100);
            Task.Run(()=>Listen(socketWatch));            
        }

        /// <summary>
        /// 等待客户端的连接,并且创建一个负责通信的Socket
        /// </summary>
        void Listen(Socket socketWatch)
        {
            //负责监听的Socket来接收客户端的连接
            while (true)
            {
                //负责跟客户端通信的Socket
                socketSend = socketWatch.Accept();
                //将远程连接的客户端的IP和Socket存入集合中
                dicSocket.Add(socketSend.RemoteEndPoint.ToString(), socketSend);
                //将远程连接的客户端的IP地址和端口号存储到下拉框中
                this.Invoke(new Action(addCbomDic));
                
                //连接成功
                this.Invoke(new Action<string>(ShowMsg), socketSend.RemoteEndPoint.ToString() + "连接成功");
                // ShowMsg(socketSend.RemoteEndPoint.ToString() + "连接成功");

                //接收客户端消息线程
                Task.Run(() => Recive(socketSend));
            
            }
            
        }

        /// <summary>
        /// 将数据添加到下拉列表中
        /// </summary>
        void addCbomDic()
        {
            cboUsers.Items.Add(socketSend.RemoteEndPoint.ToString());
        }
        
        /// <summary>
        /// 接受客户端发来的消息
        /// </summary>
        /// <param name="socketSend"></param>
        void Recive(Socket socketSend)
        {
            while (true)
            {
                try
                {
                    //客户端连接成功后,服务器应该接受客户端发来的消息
                    byte[] buffer = new byte[1024 * 1024 * 4];
                    //实际接收到的有效字节数
                    int r = socketSend.Receive(buffer);
                    if (r == 0)
                    {
                        break;
                    }
                    string str = Encoding.UTF8.GetString(buffer, 0, r);
                    this.Invoke(new Action<string>(ShowMsg), socketSend.RemoteEndPoint.ToString() + " : " + str);
                }
                catch
                {   }
            }
        }

        void ShowMsg(string str)
        {
            txtLog.AppendText(str + "\r\n");
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //关闭检查,允许子线程访问主线程
            //Control.CheckForIllegalCrossThreadCalls = false;
        }

        /// <summary>
        /// 服务器给客户端发送消息
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSend_Click(object sender, EventArgs e)
        {
            string str = txtMsg.Text;
            byte[] buffer = System.Text.Encoding.UTF8.GetBytes(str);
            List<byte> list = new List<byte>();
            list.Add(0);
            list.AddRange(buffer);

            byte[] newBuffer = list.ToArray();
            try
            {

                //获得用户在下拉框中选中的IP地址
                string ip = cboUsers.SelectedItem.ToString();
                dicSocket[ip].Send(newBuffer);
                ShowMsg(str);
            }
            catch { }
            


            //  socketSend.Send(newBuffer);
        }

        /// <summary>
        /// 选择要发送的文件 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSelect_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.InitialDirectory = @"D:\Document\Test";
            ofd.Title = "请选择要发送的文件";
            ofd.Filter = "所有文件|*.*";
            ofd.ShowDialog();

            txtPath.Text = ofd.FileName;
        }

        private void btnSendFile_Click(object sender, EventArgs e)
        {
            //获得要发送文件的路径
            string path = txtPath.Text;
            using (FileStream fsRead = new FileStream(path, FileMode.Open, FileAccess.Read))
            {
                byte[] buffer = new byte[1024 * 1024 * 8];
                int r = fsRead.Read(buffer,0,buffer.Length);
                List<byte> list = new List<byte>();
                list.Add(1);
                list.AddRange(buffer);
                byte[] newBuffer = list.ToArray();
                dicSocket[cboUsers.SelectedItem.ToString()].Send(newBuffer, 0, r+1, SocketFlags.None);
            }
        }

        /// <summary>
        /// 发送震动    
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnShake_Click(object sender, EventArgs e)
        {
            byte[] buffer = new byte[1];
            buffer[0] = 2;
            dicSocket[cboUsers.SelectedItem.ToString()].Send(buffer);
        }
    }
}

 

客户端主要代码:

客户端主要逻辑代码
 using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ClientSimple
{
    public partial class Form1 : Form
    {
        Socket socketSend;
        public Form1()
        {
            InitializeComponent();
        }

        private void btnsStart_Click(object sender, EventArgs e)
        {
            try
            {
                //创建负责通信的Socket
                socketSend = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                IPAddress ip = IPAddress.Parse(txtServer.Text.Trim());
                IPEndPoint point = new IPEndPoint(ip, Convert.ToInt32(txtPort.Text.Trim()));

                //获得要链接的远程服务器应用程序的IP地址和端口号
                socketSend.Connect(point);

                ShowMsg("连接成功");
                Task.Run(() => Recive());
            }
            catch 
            { }
        }

        /// <summary>
        /// 不停的接受服务器发来的消息
        /// </summary>
        void Recive()
        {
            while (true)
            {
                try
                {
                    //客户端连接成功后,服务器应该接受客户端发来的消息
                    byte[] buffer = new byte[1024 * 1024 * 4];
                    int r = socketSend.Receive(buffer);
                    //实际接收到的有效字节数
                    if (r == 0)
                    {
                        break;
                    }
                    if (buffer[0] == 0)
                    {
                        string str = Encoding.UTF8.GetString(buffer, 1, r-1);
                        this.Invoke(new Action<string>(ShowMsg), socketSend.RemoteEndPoint.ToString() + " : " + str);
                    }
                    else if (buffer[0] == 1)
                    {
                        this.Invoke(new Action<byte[], int>(SaveFile), buffer, r);
                    }
                    else if (buffer[0] == 2)
                    {
                        this.Invoke(new Action(Shake));
                    }
                }
                catch
                { }
            }
        }

        /// <summary>
        /// 震动
        /// </summary>
        void Shake()
        {
            for (int i = 0; i < 500; i++)
            {
                this.Location = new Point(200, 200);
                this.Location = new Point(280, 280);
            }
        }

        /// <summary>
        /// 存储文件
        /// </summary>
        void SaveFile(byte[] buffer,int r)
        {
            SaveFileDialog sfd = new SaveFileDialog();
            sfd.InitialDirectory = @"D:\Document\Test";
            sfd.Title = "请选择要保存到路径";
            sfd.Filter = "所有文件|*.*";

            sfd.ShowDialog(this);
            string path = sfd.FileName;
            using (FileStream fsWrite = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write))
            {
                fsWrite.Write(buffer, 1, r - 1);
            }
            MessageBox.Show("保存成功");
        }

        void ShowMsg(string str)
        {
            txtLog.AppendText(str + "\r\n");
        }
        /// <summary>
        /// 客户端给服务器发送消息
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSend_Click(object sender, EventArgs e)
        {
            string str = txtMsg.Text.Trim();
            byte[] buffer = System.Text.Encoding.UTF8.GetBytes(str);
            ShowMsg(str);
            socketSend.Send(buffer);
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //Control.CheckForIllegalCrossThreadCalls = false;
        }
    }
}

 

实现效果图:

总结:创建Socket过程,发送数据socket.Send()方法。接收数据socket.Receive()。

这个demo还非常简陋,有很多地方没有完善。主要目的Socket学习,所以很多能看见的Bug就没处理。客户端连接成功后,服务端要选择下拉列表中的客户端才能发信息,不然直接发就报错了。文件发送也不能为空,接收文件也不能取消,接收文件也不知道文件的后缀(类型)。。。。。。

标签:socketSend,Socket,C#,System,new,using,服务端,客户端
来源: https://www.cnblogs.com/xunzf0402/p/16546558.html

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

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

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

ICode9版权所有