步步为营-66-Socket通信

1.0 版本

1.1 服务器端

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;

namespace Server_1._0
{
    class Program
    {
        static void Main(string[] args)
        {
            //01 创建对象 关键字new
            Socket stk = new Socket(AddressFamily.InterNetwork,//设置IP地址的类型 为ip4
                SocketType.Stream, //设置传输方式 为流式传输
                ProtocolType.Tcp//设置传输协议 为Tcp
            );
            //02 绑定对象 关键字bind()
            stk.Bind(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 11011));
            //03 监听对象 关键字Listen()
            stk.Listen(10);
            Console.WriteLine("服务器启动成功!");
            //04 接受客户端 关键字Accept()     {证明Accept会阻塞线程}
            Socket client = stk.Accept();
            Console.WriteLine("服务器接受到客户端请求!");
            //05 接受报文 关键字receive
            //05-01 通过字节流传递  定义一个字节数组    {证明Receive也会阻塞线程}
            byte[] bys = new byte[1024];
            int len = client.Receive(bys);
            Console.WriteLine("服务器接收到报文");
            //06 显示接收到的字节数组
            string str = Encoding.UTF8.GetString(bys, 0, len);
            Console.WriteLine(str);
            //07 发送消息 关键字 send
            string mes = "已成功接收到你发的消息:<" + str + ">";
            client.Send(Encoding.UTF8.GetBytes(mes));
            Console.ReadKey();

        }
    }
}
Server

1.2 客户端

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;

namespace Client_1._0
{
    class Program
    {
        static void Main(string[] args)
        {
            //01 创建socket 关键字new
            Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //02 创建连接 关键字connect
            client.Connect(IPAddress.Parse("127.0.0.1"),11011);
            Console.WriteLine("与服务器创建连接");
            //03 发送消息 关键字Send
            //03-01 定义字节数组
            byte[] bys = new byte[1024];
            if (Console.ReadLine() == "1")
            {
                bys = Encoding.UTF8.GetBytes("逍遥小天狼");
                client.Send(bys);
                Console.WriteLine("向服务器发送消息!");
            }
           //04 接受消息
            //int len = 0;
            //while ((len = client.Receive(bys))>0)
            //{
            //    string s2 = Encoding.UTF8.GetString(bys, 0, len);
            //    Console.Write(s2);

            //}
            byte [] by = new byte[1024];
            int len = client.Receive(by);
            Console.WriteLine(Encoding.UTF8.GetString(by,0,len));

            Console.ReadKey();
        }
    }
}
Client

2.0 版本

2.1 服务器

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Runtime.Remoting.Contexts;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Server_1._0
{
    class Program
    {
        static void Main(string[] args)
        {
            //01 创建对象 关键字new
            Socket stk = new Socket(AddressFamily.InterNetwork,//设置IP地址的类型 为ip4
                SocketType.Stream, //设置传输方式 为流式传输
                ProtocolType.Tcp//设置传输协议 为Tcp
            );
            //02 绑定对象 关键字bind()
            stk.Bind(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 11011));
            //03 监听对象 关键字Listen()
            stk.Listen(10);
            Console.WriteLine("服务器启动成功!");
            #region 旧的代码
            ////04 接受客户端 关键字Accept()     {证明Accept会阻塞线程}
            //Socket client = stk.Accept();
            //Console.WriteLine("服务器接受到客户端请求!");
            ////05 接受报文 关键字receive
            ////05-01 通过字节流传递  定义一个字节数组    {证明Receive也会阻塞线程}
            //byte[] bys = new byte[1024];
            //int len = client.Receive(bys);
            //Console.WriteLine("服务器接收到报文");
            ////06 显示接收到的字节数组
            //string str = Encoding.UTF8.GetString(bys, 0, len);
            //Console.WriteLine(str); 
            #endregion

            #region 新的代码 -- 通过 线程解决阻塞问题
            Thread thClient = new Thread((s) =>
            {
                while (true)
                {
                    //04 接受客户端 关键字Accept
                    Socket server = s as Socket;
                    Socket client = server.Accept();
                    //04-01 输出具体连接的客户端
                    Console.WriteLine("---客户端" + client.RemoteEndPoint + "连接");
                    //05 获取报文
                    Thread thReceive = new Thread((c) =>
                    {
                        Socket cClient = c as Socket;
                        byte[] bs = new byte[1024];
                        int len;
                        while ((len = cClient.Receive(bs)) > 0)
                        {
                            Console.WriteLine(Encoding.UTF8.GetString(bs, 0, len));
                        }
                    });
                    thReceive.IsBackground = true;
                    thReceive.Start(client);
                }
            });
            thClient.IsBackground = true;
            thClient.Start(stk);
            #endregion
            //07 发送消息 关键字 send
            //string mes = "已成功接收到你发的消息:<" + str + ">";
           // client.Send(Encoding.UTF8.GetBytes(mes));
            Console.ReadKey();

        }
    }
}
View Code

2.2 客户端

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;

namespace Client_1._0
{
    class Program
    {
        static void Main(string[] args)
        {
            //01 创建socket 关键字new
            Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //02 创建连接 关键字connect
            client.Connect(IPAddress.Parse("127.0.0.1"),11011);
            Console.WriteLine("与服务器创建连接");
            //03 发送消息 关键字Send
            //03-01 定义字节数组
            byte[] bys = new byte[1024];
            string str = string.Empty;
            while ((str = Console.ReadLine()) != "1")
            {
                bys = Encoding.UTF8.GetBytes(str);
                client.Send(bys);
                Console.WriteLine("向服务器发送消息!");
            }
           //04 接受消息
            #region 04-01 接受消息01
            //int len = 0;
            //while ((len = client.Receive(bys))>0)
            //{
            //    string s2 = Encoding.UTF8.GetString(bys, 0, len);
            //    Console.Write(s2);

            //} 
            #endregion
            #region 04-02 接受消息2
            //byte[] by = new byte[1024];
            //int len = client.Receive(by);
            //Console.WriteLine(Encoding.UTF8.GetString(by, 0, len));
            
            #endregion

            Console.ReadKey();
        }
    }
}
View Code

 3.0 版本  Winfrom程序

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;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Server_Form
{
    public partial class frmServer : Form
    {
        public frmServer()
        {
            InitializeComponent();
        }
        #region 00 客户端字典
        private Dictionary<string,Socket> dicClient = new Dictionary<string, Socket>( );
        #endregion
        #region 01 启动服务器
        private void button1_Click(object sender, EventArgs e)
        {
            //01 创建连接对象
            Socket serverSCK = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //02 绑定
            serverSCK.Bind(new IPEndPoint(IPAddress.Parse("127.0.0.1"),11011));
            //03 监听
            serverSCK.Listen(10);
            txtMsg.Text = "服务器启动成功!
";
            //04 接受客户端的线程
            Thread thClient = new Thread((server) =>
            {
                Socket serverSocket = server as Socket;
                //05 接受客户端
                while (true)
                {
                    Socket clientSCK = serverSocket.Accept();

                    txtMsg.Invoke(new Action<string> ( (s) =>
                    {
                        //01 提示连接成功
                        txtMsg.Text += s + "连接成功!
";
                        //02 将客户信息显示到列表中
                        clientList.Invoke(new Action<string>((ip) =>
                        {
                            clientList.Items.Add(ip);
                        }),s);
                        //03 将客户端放入到字典中
                        dicClient.Add(s, clientSCK);
                    }),clientSCK.RemoteEndPoint.ToString());
                    //06 接受客户端传来的报文的线程
                    Thread thReceive = new Thread((clientSocket) =>
                    {
                        Socket concentSocket = clientSocket as Socket;
                        byte[] bys = new byte[1024];
                        int len = 0;
                        while ((len = concentSocket.Receive(bys))>0)
                        {
                           //处理请求信息
                            txtMsg.Invoke(new Action<string>((s) =>
                            {
                                txtMsg.Text += s + "
";
                            }),concentSocket.RemoteEndPoint.ToString()+":"+Encoding.UTF8.GetString(bys,0,len));
                        }
                    });
                    thReceive.IsBackground = true;
                    thReceive.Start(clientSCK);
                }
            });
            thClient.IsBackground = true;
            thClient.Start(serverSCK);
        } 
        #endregion

        #region 06 发送消息
        private void btnSend_Click(object sender, EventArgs e)
        {
            //01 获得连接的客户端的字符串
            string clientKey = clientList.SelectedItem.ToString();
            //02 根据字符串获得客户端
            Socket clientSCK = dicClient[clientKey];
            //03 发送消息
            clientSCK.Send(Encoding.UTF8.GetBytes(txtSendMsg.Text));
        } 
        #endregion

       

        
    }
}
Server
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;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Client_Form
{
    public partial class FtmClient : Form
    {
        public FtmClient()
        {
            InitializeComponent();
        }
        #region 00 声明全局变量

        private Socket client;
        #endregion
        #region 01 连接服务器
        private void btnConnect_Click(object sender, EventArgs e)
        {
            //01 创建连接对象
              client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //02 连接 
            client.Connect(IPAddress.Parse(txtIP.Text),int.Parse(txtPort.Text));
            txtSendMsg.Text += "与服务器连接成功!
";
            //03 接受响应消息
            Thread thReceive = new Thread((clientSck) =>
            {
                Socket clientRecive = clientSck as Socket;
                byte[] bys = new byte[1024];
                int len = 0;
                while ((len = clientRecive.Receive(bys))>0)
                {
                    txtRecMsg.Invoke(new Action<string>(s =>
                    {
                        txtRecMsg.Text += s + "
";
                    }),Encoding.UTF8.GetString(bys,0,len));
                }
                
            });
            thReceive.IsBackground = true;
            thReceive.Start(client);
        } 
        #endregion

        #region 02 关闭窗体时清空socket 否则连接会出错
        private void FtmClient_FormClosed(object sender, FormClosedEventArgs e)
        {
            client.Shutdown(SocketShutdown.Both);
            client.Close();
            client.Dispose();
        } 
        #endregion

        #region 03 发送消息
        private void btnSend_Click(object sender, EventArgs e)
        {
            //01 判断是否为空
            if (client!= null)
            {
                client.Send(Encoding.UTF8.GetBytes(txtSendMsg.Text));
            }
        } 
        #endregion
    }
}
Client

原文地址:https://www.cnblogs.com/YK2012/p/6920839.html