C#实现Socket的消息收发,ServerSocket,ClientSocket

这篇具有很好参考价值的文章主要介绍了C#实现Socket的消息收发,ServerSocket,ClientSocket。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

        知道Socket原理,但是一直没有在代码里面尝试怎么操作,闲来无事实现了一个初步的Socket服务器和客户端连接的Demo,但是没有实现更高级一点的系列化传输,加解密处理以及队列和断线重连等处理,感兴趣的话可以自己再尝试尝试。
主要分服务器Socket和客户端Socket,只用了简单的字符串转byte[]的传递测试收发消息。
服务器这边的话实现了个初步的SocketID管理。
分ServerSocket和ClientSocket来具体实现服务器与客户端的收发逻辑。

ServerSocket的实现,单独启个工程。

namespace ServerSocket
{
    class Program
    {
        private static ServerSocketDemo _serverSocket = null;

        static void Main(string[] args)
        {
            _serverSocket = new ServerSocketDemo();
            _serverSocket.Initialize(OnReceiveMsgCallback);
        }

        private static void OnReceiveMsgCallback(int socketId, string msg)
        {
            if (!string.IsNullOrEmpty(msg))
            {
                //给所有已连接的客户端发送消息,类似于广播
                if (msg.Contains("all"))
                {
                    _serverSocket.SendMsgToAll("嘿嘿嘿");
                }
                //只给当前发送消息来的客户端回消息,点对点
                if (msg.Contains("single"))
                {
                    _serverSocket.SendMsgByID(socketId, string.Format("你好,{0},收到了你的消息!", socketId));
                }
            }
        }
    }
}
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;

namespace ServerSocket
{
    
    public class ServerSocketDemo
    {
        //IP和端口
        private string IP = "127.0.0.1";
        private int    PORT = 9527;
        private Socket _serverSocket = null;
        //收取数据的缓冲区,每次读取多少数据的缓存
        private byte[] _receiveBuff = new byte[1024];
        //用来处理ClientSocket的ID
        private int _socketID = 0;
        //已连接的客户端Socket
        private Dictionary<int, SocketInfo> _sockets = null;
        //收到客户端消息的回调
        private Action<int, string> _onReceiveMsgCall = null;
        public void Initialize(Action<int, string> receiveMsgCall)
        {
            _onReceiveMsgCall = receiveMsgCall;
            _sockets = new Dictionary<int, SocketInfo>();
            //绑定IP和端口,启动Socket
            _serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            IPAddress ipAddress = IPAddress.Parse(IP);
            IPEndPoint ipEndpoint = new IPEndPoint(ipAddress, PORT);
            _serverSocket.Bind(ipEndpoint);
            _serverSocket.Listen(20);
            Console.WriteLine(string.Format("ServerSocket:{0}启动成功!", _serverSocket.LocalEndPoint.ToString()));
            //开个线程接收客户端的消息
            Thread socketTread = new Thread(new ThreadStart(OnClientConnected));
            socketTread.IsBackground = true;
            socketTread.Start();
            Console.ReadKey();
        }

        private void OnClientConnected()
        {
            while (true)
            {
                Socket clientSocket = _serverSocket.Accept();
                Console.WriteLine(string.Format("{0}连接成功!", clientSocket.LocalEndPoint.ToString()));
                Thread receiveThread = new Thread(OnReceiveMsg);
                receiveThread.IsBackground = true;
                //给客户端Socket生成ID并且记录客户端Socket的连接
                SocketInfo socketInfo = new SocketInfo();
                _socketID++;
                socketInfo.ID = _socketID;
                socketInfo.ClientSocket = clientSocket;
                //把连接上的Socket保存起来
                _sockets.Add(socketInfo.ID, socketInfo);
                receiveThread.Start(socketInfo);
            }
        }

        private void OnReceiveMsg(object info)
        {
            SocketInfo socketInfo = info as SocketInfo;
            Socket receiveSocket = socketInfo.ClientSocket;
            while (true)
            {
                try
                {
                    //读取客户端发来的数据,这里没考虑类的系列化,只简单测试字符串的收发
                    int recvLen = receiveSocket.Receive(_receiveBuff);
                    string content = Encoding.UTF8.GetString(_receiveBuff, 0, recvLen);
                    Console.WriteLine(string.Format("收到用户【{0}】发来的消息:{1}", socketInfo.ID, content));
                    //做个回调,处理收到的数据
                    if (_onReceiveMsgCall != null)
                    {
                        _onReceiveMsgCall(socketInfo.ID, content);
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine("接收消息异常:" + ex.Message);
                    receiveSocket.Shutdown(SocketShutdown.Both);
                    receiveSocket.Close();
                    return;
                }
            }
        }

        /// <summary>
        /// 根据记录的客户端SocketID进行单点的消息发送
        /// </summary>
        /// <param name="socketId"></param>
        /// <param name="msg"></param>
        public void SendMsgByID(int socketId, string msg)
        {
            if (_sockets.ContainsKey(socketId))
            {
                Socket clientSocket = _sockets[socketId].ClientSocket;
                if (clientSocket.Connected)
                {
                    byte[] bytes = Encoding.UTF8.GetBytes(msg);
                    clientSocket.Send(bytes);
                }
            }
        }

        /// <summary>
        /// 发送给所有已连接的客户端
        /// </summary>
        /// <param name="msg"></param>
        public void SendMsgToAll(string msg)
        {
            var iter = _sockets.GetEnumerator();
            while (iter.MoveNext())
            {
                byte[] bytes = Encoding.UTF8.GetBytes(msg);
                iter.Current.Value.ClientSocket.Send(bytes);
            }
        }

        private class SocketInfo
        {
            /// <summary>
            /// 记录Socket的ID
            /// </summary>
            public int ID { get; set; }
            /// <summary>
            /// 客户端的Socket连接
            /// </summary>
            public Socket ClientSocket { get; set; }
        }
    }
}

ClientSocket的实现

using System;

namespace ClientSocket
{
    class Program
    {
        static void Main(string[] args)
        {
            ClientSocketDemo clientSocket = new ClientSocketDemo();
            clientSocket.Initialize();
            clientSocket.SendMsg("你好!");
            while (true)
            {
                //输入数据按回车给服务器发消息
                string newMsg = Console.ReadLine();
                clientSocket.SendMsg(newMsg);
            }
        }
    }
}
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;

namespace ClientSocket
{
    public class ClientSocketDemo
    {
        private string IP = "127.0.0.1";
        private int PORT = 9527;
        private Socket _clientSocket = null;
        private byte[] _buffer = null;
        public void Initialize()
        {
            _clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            _buffer = new byte[1024];
            IPAddress ip = IPAddress.Parse(IP);
            IPEndPoint endPoint = new IPEndPoint(ip, PORT);
            try
            {
                _clientSocket.Connect(endPoint);
                Console.WriteLine(string.Format("连接{0}服务器成功!", _clientSocket.LocalEndPoint.ToString()));
            }
            catch (Exception ex)
            {
                Console.WriteLine(string.Format("连接服务器失败:\n"+ ex.Message));
                return;
            }
            //开线程接收服务器下来的数据
            Thread receiveThread = new Thread(OnReceiveMsg);
            receiveThread.IsBackground = true;
            receiveThread.Start();
        }

        /// <summary>
        /// 接收服务器消息
        /// </summary>
        private void OnReceiveMsg()
        {
            while (true)
            {
                try
                {
                    int receiveLen = _clientSocket.Receive(_buffer);
                    string receiveMsg = Encoding.UTF8.GetString(_buffer, 0, receiveLen);
                    Console.WriteLine(string.Format("收到服务器消息:" + receiveMsg));
                }
                catch (Exception ex)
                {
                    Console.WriteLine("接收消息异常:\n" + ex.Message);
                    _clientSocket.Shutdown(SocketShutdown.Both);
                    _clientSocket.Dispose();
                    Console.ReadKey();
                }
            }
        }

        /// <summary>
        /// 给服务器发消息
        /// </summary>
        public void SendMsg(string msg)
        {
            if (_clientSocket != null && _clientSocket.Connected)
            {
                _clientSocket.Send(Encoding.UTF8.GetBytes(msg));
            }
        }
    }
}

测试:

先启动ServerSocket,然后启动两个ClientSocket.

客户端给服务器发all代表广播给所有客户端,给服务器发single代表只点对点的进行回消息。

测试结果如下:

c# clientsocket,Unity,服务器,网络,java

 文章来源地址https://www.toymoban.com/news/detail-598465.html

到了这里,关于C#实现Socket的消息收发,ServerSocket,ClientSocket的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包