C#之Socket编程进阶

C#之Socket编程

代码在VS编辑器上创建,选择“控制台控制程序”

代码注释比较详细,在此就不说废话了

首先粘贴服务端代码

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

using System.Threading;
using System.Net;
using System.Net.Sockets;

namespace ServerSocket
{
    //接收,监听,发送的类,自己创建
    public class StateObject
    {
        public byte[] buffer = new byte[128];
        public int offset = 0;
        public Socket socket = null;

        public StateObject() { }
    }

    public class ServerSocketClass
    {
        //单利
        public static ServerSocketClass instance = null;
        //用于存放所有的线程
        public List<Thread> threadList = new List<Thread>();
        //用于存放所有的连接的Socket对象
        public List<Socket> AcceptSocketList = new List<Socket>();
        public Socket serverSocket;
        //创建一个单利方法,避免重复创建对象
        public static ServerSocketClass Init()
        {
            if (instance == null)
            {
                instance = new ServerSocketClass();
            }
            return instance;
        }

        public ServerSocketClass()
        {
            //端口号
            int port = 11111;
            //IP地址
            IPAddress ipAddress = IPAddress.Parse("127.0.0.1");
            //实例化Socket对象,参数1为Socket类的寻址方案,参数2指定Socket的类型,参数3为Socket使用的协议
            Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //
            IPEndPoint ipEndPoint = new IPEndPoint(ipAddress, port);
            //服务端绑定IP和端口号
            serverSocket.Bind(ipEndPoint);
            //开始监听客户端的连接,并且设定最多可以接受10个客户端的连接
            serverSocket.Listen(10);
            Console.WriteLine("创建成功");
            //创建一个线程,服务端开始接收连接
            ParameterizedThreadStart threadStart = new ParameterizedThreadStart(SocketBeginAccept);
            Thread thread = new Thread(threadStart);
            thread.IsBackground = true;
            thread.Start(serverSocket);
            threadList.Add(thread);
        }

        //异步接受连接
        public void SocketBeginAccept(object s)
        {
            Socket socket = (Socket)s;
            try
            {
                while (true)
                {
                    StateObject stateObject = new StateObject();
                    stateObject.socket = socket;
                    //开启异步接收连接
                    socket.BeginAccept(new AsyncCallback(AcceptCallBack), stateObject);
                    Thread.Sleep(100); //线程暂停 100 毫秒
                }
            }
            catch
            { }
        }
        //异步连接的回调方法
        public void AcceptCallBack(IAsyncResult acccept)
        {
            //获取 StateObject对象
            StateObject stateObject = (StateObject)acccept.AsyncState;
            serverSocket = stateObject.socket;
            Socket clientSocket = serverSocket.EndAccept(acccept);
            Console.WriteLine("接收到客户端连接 server  {0};    client : {1};   可以发消息啦", serverSocket.LocalEndPoint, clientSocket.RemoteEndPoint);
            //将客户端连接存放进集合中
            AcceptSocketList.Add(clientSocket);
            //在回调方法中再次调用接收连接的线程
            serverSocket.BeginAccept(new AsyncCallback(AcceptCallBack), stateObject);
        }
        //创建接收消息的线程
        public void CreateThreadReceive(Socket clientSocket)
        {
            ParameterizedThreadStart threadStart = new ParameterizedThreadStart(SocketBeginReceive);
            Thread thread = new Thread(threadStart);
            thread.IsBackground = true;
            thread.Start(clientSocket);
            threadList.Add(thread);
        }
        //接收消息的线程调用该方法
        public void SocketBeginReceive(object s)
        {
            Socket socket = (Socket)s;
            StateObject stateObject = new StateObject();
            stateObject.socket = socket;
            try
            {
                while (true)
                {
                    //异步接收客户端发来的信息
                    socket.BeginReceive(stateObject.buffer, 0, stateObject.buffer.Length, 0, new AsyncCallback(ReceiveCallBack), stateObject);
                    Thread.Sleep(100);
                }
            }
            catch { CloseSocket(socket); }
        }
        //接收消息的回调方法
        public void ReceiveCallBack(IAsyncResult receive)
        {
            StateObject stateObject = (StateObject)receive.AsyncState;
            Socket s = stateObject.socket;
            //回调方法中要调用该方法
            int read = s.EndReceive(receive);
            if (read > 0)
            {
                try
                {
                    //开启异步接收消息
                    s.BeginReceive(stateObject.buffer, 0, stateObject.buffer.Length, 0, new AsyncCallback(ReceiveCallBack), stateObject);
                }
                catch { }
            }
            else
            {
                CloseSocket(s);
            }

            ASCIIEncoding encoding = new ASCIIEncoding();
            string str = encoding.GetString(stateObject.buffer);
            //输出客户端发来的消息
            Console.WriteLine("客户端 :{0}", str);
        }

        //服务端向客户端发送消息
        public void ServerSendMessage(Socket client, string message)
        {
            StateObject stateObject = new StateObject();
            stateObject.socket = client;
            try
            {
                //将字符串转换为字节
                stateObject.buffer = Encoding.UTF8.GetBytes(message);
                //开启异步发送
                client.BeginSend(stateObject.buffer, 0, stateObject.buffer.Length, 0, new AsyncCallback(SendMessageCallBack), stateObject);
            }
            catch (Exception e)
            {
                Console.WriteLine("ddd {0}", e);
                CloseSocket(client);
            }
        }
        //服务端发送消息的回调方法
        public void SendMessageCallBack(IAsyncResult send)
        {
            StateObject stateObject = (StateObject)send.AsyncState;
            Socket client = stateObject.socket;

            //int count = client.EndSend(send);//获取发送消息的长度,
            //获取发送的消息, 转换为字符串
            //string str = new ASCIIEncoding().GetString(stateObject.buffer);
            //将发送的消息打印到控制台
            //Console.WriteLine("服务端:发送消息长度{0}:   内容{1}", count.ToString(), new ASCIIEncoding().GetString(stateObject.buffer));
        }

        //销毁线程的方法
        public void CloseThread()
        {
            foreach (Thread thread in threadList)
            {
                if (thread.IsAlive)
                {
                    thread.Abort();
                }
            }
        }
        //断开Socket
        public void CloseSocket(Socket s)
        {
            if (!s.Connected)
            {
                s.Shutdown(SocketShutdown.Both);
                s.Close();
            }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            //实例化客户端类对象
            ServerSocketClass serverSocketClass = ServerSocketClass.Init();
            //开启接收消息的方法
            StartReceive(serverSocketClass);

            string str = "";
            while (true)
            {
                str = Console.ReadLine();
                StartSendMessage(serverSocketClass, str);
                Thread.Sleep(100);
            }
        }
        //调用该方法接收客户端发来的消息
        public static void StartReceive(ServerSocketClass serverSocketCla)
        {
            ServerSocketClass serverSocketClass = (ServerSocketClass)serverSocketCla;
            while (true)
            {
                //为了能够监听连接的客户端发来的消息,在没有客户端连接时一直循环调用
                if (serverSocketClass.AcceptSocketList.Count > 0)
                {
                    foreach (Socket socket in serverSocketClass.AcceptSocketList)
                    {
                        serverSocketClass.CreateThreadReceive(socket);
                    }
                    //当有一个客户端连接到服务端时,退出循环
                    break;
                }
                Thread.Sleep(100);
            }
        }

        //手动输入向客户端发送消息
        public static void StartSendMessage(ServerSocketClass serverSocketCla, string message)
        {
            ServerSocketClass serverSocketClass = (ServerSocketClass)serverSocketCla;
            //向所有连接着的客户端发送消息
            foreach (Socket socket in serverSocketClass.AcceptSocketList)
            {
                serverSocketClass.ServerSendMessage(socket, message);
            }
        }

    }
}


客户端代码如下:

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

using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace ClientSocket
{
    //接收,监听,发送消息的类,自己创建
    public class StateObject
    {
        public Socket socket = null;
        public byte[] buffer = new byte[128];
        public int offset = 0;

        public StateObject() { }
    }

    public class ClientSocketClass
    {
        //单利
        public static ClientSocketClass instance = null;
        //用于存放所有的线程
        public List<Thread> threadList = new List<Thread>();
        //用于存放连接的服务端
        public List<Socket> socketList = new List<Socket>();
        public Socket clientSocket;
        //创建一个单利方法
        public static ClientSocketClass Init()
        {
            if (instance == null)
            {
                instance = new ClientSocketClass();
            }
            return instance;
        }

        public ClientSocketClass()
        {
            //端口号
            int port = 11111;
            //IP地址
            IPAddress ipAddress = IPAddress.Parse("127.0.0.1");
            IPEndPoint ipEndPoint = new IPEndPoint(ipAddress, port);
            clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            try
            {
                StateObject stateObject = new StateObject();
                stateObject.socket = clientSocket;
                clientSocket.BeginConnect(ipEndPoint, new AsyncCallback(ConnectCallBack), stateObject);
            }
            catch
            { }
        }
        //异步连接的回调方法
        public void ConnectCallBack(IAsyncResult connect)
        {
            StateObject stateObject = (StateObject)connect.AsyncState;
            Socket clientSocket = stateObject.socket;
            Console.WriteLine("成功连接服务器,本地 : {0};     服务器      {1};    可以发消息啦", clientSocket.LocalEndPoint, clientSocket.RemoteEndPoint);

            try
            {
                clientSocket.EndConnect(connect);
            }
            catch { }
            //将连接到的服务端存放进集合
            socketList.Add(clientSocket);
        }
        //创建接收消息的线程
        public void CreateThreadReceive(Socket clientSocket)
        {
            //开启一个接收消息的线程
            ParameterizedThreadStart threadStart = new ParameterizedThreadStart(SocketBeginReceive);
            Thread thread = new Thread(threadStart);
            thread.IsBackground = true;
            thread.Start(clientSocket);
            threadList.Add(thread);
        }
        //发送消息的方法
        public void ClientSendMessage( Socket client, string message)
        {
            StateObject stateObject = new StateObject();
            stateObject.socket = client;
            try
            {           
                stateObject.buffer = Encoding.UTF8.GetBytes(message);
                //开启异步发送消息
                client.BeginSend(stateObject.buffer, 0, stateObject.buffer.Length, 0, new AsyncCallback(SendMessageCallBack), stateObject);
            }
            catch (Exception e){
                Console.WriteLine("ddd {0}", e);
                CloseSocket(client);
            }
        }
        //发送消息的回调方法
        public void SendMessageCallBack(IAsyncResult send)
        {
            StateObject stateObject = (StateObject)send.AsyncState;
            Socket client = stateObject.socket;

            //int count = client.EndSend(send);//获取发送消息的长度
            //获取发送的消息, 转换为字符串
            //string str = new ASCIIEncoding().GetString(stateObject.buffer);
            //在控制台打印
            //Console.WriteLine("客户端:发送消息长度{0}:  内容{1}", count.ToString(), new ASCIIEncoding().GetString( stateObject.buffer));
        }

        //调用该方法发送消息, 参数为要发送的 Socket对象
        public void SocketBeginReceive(object s)
        {
            Socket socket = (Socket)s;
            StateObject stateObject = new StateObject();
            stateObject.socket = socket;
            try
            {
                while (true)
                {          
                    //异步接收客户端发来的信息
                    socket.BeginReceive(stateObject.buffer, 0, stateObject.buffer.Length, 0, new AsyncCallback(ReceiveCallBack), stateObject);
                    Thread.Sleep(100);
                }
            }
            catch { CloseSocket(socket); }
        }
        //接收消息的回调方法
        public void ReceiveCallBack(IAsyncResult receive)
        {
            StateObject stateObject = (StateObject)receive.AsyncState;
            Socket s = stateObject.socket;
            //接收消息的回调方法要调用 EndReceive() 方法
            int read = s.EndReceive(receive);
            if (read > 0)
            {
                try
                {
                    ASCIIEncoding encoding = new ASCIIEncoding();
                    string str = encoding.GetString(stateObject.buffer);
                    Console.WriteLine("服务端 :{0}", str);// 输出服务端发来的消息
                    s.BeginReceive(stateObject.buffer, 0, stateObject.buffer.Length, 0, new AsyncCallback(ReceiveCallBack), stateObject);
                }
                catch { }
            }
            else
            {
                CloseSocket(s);
            }
        }
        //销毁线程
        public void CloseThread()
        {
            foreach (Thread thread in threadList)
            {
                if (thread.IsAlive)
                {
                    thread.Abort();
                }
            }
        }
        //断开Socket
        public void CloseSocket(Socket s)
        {
            if (!s.Connected)
            {
                s.Shutdown(SocketShutdown.Both);
                s.Close();
            }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            ClientSocketClass clientSocketClass = ClientSocketClass.Init();
            //开始接收
            StartReceive( clientSocketClass);

            string str = "";
            while (true)
            {
                str = Console.ReadLine();//输入要发送的消息
                //向服务器发送消息
                clientSocketClass.ClientSendMessage(clientSocketClass.clientSocket, str);
                Thread.Sleep(100);
            }
        }
        //开始接收消息
        public static void StartReceive(ClientSocketClass clientSocketCla)
        {
            ClientSocketClass clientSocketClass = clientSocketCla;
            while (true)
            {
                //为了能够监听连接的服务端发来的消息,在没有连接到服务端时一直调用
                if (clientSocketClass.socketList.Count > 0)
                {
                    foreach (Socket socket in clientSocketClass.socketList)
                    {
                        clientSocketClass.CreateThreadReceive(socket);
                    }
                    //当连接到服务端时,退出循环
                    break;
                }
            }
        }
    }
}


创建两个项目,一个粘贴服务端代码,一个粘贴客户端代码

(1)运行服务端项目,结果如下



(2)运行客户端,如下图



(3)接下来就可以相互发送消息啦






























  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
“中级/进阶篇”讲解特点与内容:         本“中级”与“进阶”篇, 是面向初中级游戏研发人员,以及Unity中高级学习者。为了更加深入的刨析各个语法的本质,我们采用反编译解读IL中间语言的方式,来解构语法重点与难点。 中级篇内容主要讲解: .Net 框架、里氏替换原则(LSP)、类的属性极其本质特性、IS ,AS 关键字、字符串的“驻留性” 原理、深入解析Equals() 原理、枚举类型、自定义集合、深入解析动态集合特性与内部原理、泛型集合、泛型约束、初级委托与事件讲解等。 进阶篇是在中级篇的基础之上,进一步研究与讲解关于IO操作、序列化、正则表达式、系统委托(Action、Function、Predicate等)、反射原理与特性、Linq查询表达式、多线程、线程池、任务、Socket套接字编程(Tcp与UDP协议),以及最后使用Unity开发具备实战价值的通讯聊天程序等。C#进阶篇”教学详细说明如下:1: IO操作与序列化      学习文件、目录、二进制文件、文本文件的读取与写入底层原理。学习文件序列化与反序列化技能。2: 正则表达式      学习正则表达式的强大作用与常用原字符的含义与应用场景。3: 深入委托与事件      学习Action、Func、Predicate 系统内置委托类型,已经适用场合。学习匿名方法、Lambda表达式。深入解析委托与事件的区别。4: 反射与特性      学习反射的概念与动态调用的重要应用价值,以及Type、Assembley核心类等,最后讲解“特性”技术。5: Linq 查询表达式     学习Linq 查询表达式对于“对象集合”(支持IEnumberable 或IEnumberable) 以及SQL数据库、XML文档方面的强大查询功能。    6: 多线程     学习多线程以及线程传参、线程取得返回数值技术,前台与后台线程、线程的同步、线程池、任务等技术。   7: Socket套接字通讯     学习Socket套接字通讯中,Tcp与UPD通讯协议的不同应用场景,以及各自的演示示例,最后用Unity开发一款实用性的聊天通讯工具。温习提示:           本C# for Unity 使用Virtual Studio2012,以及Unity5.2 进行开发与讲解。(学员使用更高版本,对学习没有任何影响)。      A:《C# For Unity系列之入门篇》https://edu.csdn.net/course/detail/4560B:《C# For Unity系列之基础篇》https://edu.csdn.net/course/detail/4595C: 《C# For Unity系列之中级篇》https://edu.csdn.net/course/detail/24422

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值