我的编程空间,编程开发者的网络收藏夹
学习永远不晚

C#之Socket客户端全过程

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

C#之Socket客户端全过程

C#开发Socket客户端

我们先新建一个类:SocketClientAsync。

注意点:

1、由于Socket通讯是发送到缓存区内的数据是覆盖,而不是新的,也就是说如果我们第一次发送的内容是 byte[]{0x11,0x22};而第二次发送的内容是byte[]{0x22}。那么我们的服务端在第二次接受到的数据是byte[]{0x22,0x22}。

所以我们需要在Socket.Send(byte[] mes)方法里面声明

byte[] buffer = new byte[1024];
for (int i = 0; i < buffer.Length; i++)
 {
        buffer[i] = 0x00;
}

起到的作用就是每次在发送新的内容到服务端的时候,会将所有的旧的内容替换掉;

2、关闭连接之前需要将通知服务端停止发送和接受,也就是

this.clientSocket.Shutdown(SocketShutdown.Both);

中断套接字连接:通知服务器端或客户端停止接收和发送数据。

通知完成之后如果客户端还连接着再进行自己的连接断开

if (this.clientSocket.Connected)
 {
         this.clientSocket.Close();
}

3、具体类的代码见下图,可以直接使用

    #region SocketClient客户端
    public class SocketClientAsync
    {
        #region 声明变量
        public string IPAdress;
        public bool connected = false;
        public Socket clientSocket;
        private IPEndPoint hostEndPoint;
        private int Flag = 0;
        private AutoResetEvent autoConnectEvent = new AutoResetEvent(false);
        private SocketAsyncEventArgs lisnterSocketAsyncEventArgs;
        public delegate void StartListeHandler();
        public event StartListeHandler StartListen;
        public delegate void ReceiveMsgHandler(byte[] info, int i);
        public event ReceiveMsgHandler OnMsgReceived;
        private List<SocketAsyncEventArgs> s_lst = new List<SocketAsyncEventArgs>();
        #endregion
        #region 构造函数
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="hostName"></param>
        /// <param name="port"></param>
        /// <param name="i"></param>
        public SocketClientAsync(string hostName, int port, int i)
        {
            Flag = i;
            IPAdress = hostName;
            IPAddress[] hostAddresses = Dns.GetHostAddresses(hostName);
            this.hostEndPoint = new IPEndPoint(hostAddresses[hostAddresses.Length - 1], port);
            this.clientSocket = new Socket(this.hostEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
        }
        #endregion
        #region 开始连接服务端
        /// <summary>
        /// 连接服务端
        /// </summary>
        /// <returns></returns>
        private bool Connect()
        {
            using (SocketAsyncEventArgs args = new SocketAsyncEventArgs())
            {
                args.UserToken = this.clientSocket;
                args.RemoteEndPoint = this.hostEndPoint;
                args.Completed += new EventHandler<SocketAsyncEventArgs>(this.OnConnect);
                this.clientSocket.ConnectAsync(args);
                bool flag = autoConnectEvent.WaitOne(5000);
                if (this.connected)
                {
                    this.lisnterSocketAsyncEventArgs = new SocketAsyncEventArgs();
                    byte[] buffer = new byte[1024];
                    this.lisnterSocketAsyncEventArgs.UserToken = this.clientSocket;
                    this.lisnterSocketAsyncEventArgs.SetBuffer(buffer, 0, buffer.Length);
                    this.lisnterSocketAsyncEventArgs.Completed += new EventHandler<SocketAsyncEventArgs>(this.OnReceive);
                    this.StartListen();
                    return true;
                }
                return false;
            }
        }
        #endregion
        #region 判断有没有连接上服务端
        /// <summary>
        /// 判断有没有连接上
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnConnect(object sender, SocketAsyncEventArgs e)
        {
            this.connected = (e.SocketError == SocketError.Success);
            autoConnectEvent.Set();
        }
        #endregion
        #region 发送数据到服务端
        /// <summary>
        /// 发送
        /// </summary>
        /// <param name="mes"></param>
        public void Send(byte[] mes)
        {
            if (this.connected)
            {
                EventHandler<SocketAsyncEventArgs> handler = null;
                //byte[] buffer = Encoding.Default.GetBytes(mes);
                byte[] buffer = new byte[1024];
                for (int i = 0; i < buffer.Length; i++)
                {
                    buffer[i] = 0x00;
                }
                Array.Copy(mes, 0, buffer, 0, mes.Length);
                SocketAsyncEventArgs senderSocketAsyncEventArgs = null;
                lock (s_lst)
                {
                    if (s_lst.Count > 0)
                    {
                        senderSocketAsyncEventArgs = s_lst[s_lst.Count - 1];
                        s_lst.RemoveAt(s_lst.Count - 1);
                    }
                }
                if (senderSocketAsyncEventArgs == null)
                {
                    senderSocketAsyncEventArgs = new SocketAsyncEventArgs();
                    senderSocketAsyncEventArgs.UserToken = this.clientSocket;
                    senderSocketAsyncEventArgs.RemoteEndPoint = this.clientSocket.RemoteEndPoint;
                    if (handler == null)
                    {
                        handler = delegate(object sender, SocketAsyncEventArgs _e)
                        {
                            lock (s_lst)
                            {
                                s_lst.Add(senderSocketAsyncEventArgs);
                            }
                        };
                    }
                    senderSocketAsyncEventArgs.Completed += handler;
                }
                senderSocketAsyncEventArgs.SetBuffer(buffer, 0, buffer.Length);
                this.clientSocket.SendAsync(senderSocketAsyncEventArgs);
            }
            else
            {
                this.connected = false;
            }
        }
        #endregion
        #region 监听服务端
        /// <summary>
        /// 监听服务端
        /// </summary>
        public void Listen()
        {
            if (this.connected && this.clientSocket != null)
            {
                try
                {
                    (lisnterSocketAsyncEventArgs.UserToken as Socket).ReceiveAsync(lisnterSocketAsyncEventArgs);
                }
                catch (Exception)
                {
                }
            }
        }
        #endregion
        #region 断开服务端的连接
        /// <summary>
        /// 断开连接
        /// </summary>
        /// <returns></returns>
        private int Disconnect()
        {
            int res = 0;
            try
            {
                this.clientSocket.Shutdown(SocketShutdown.Both);
            }
            catch (Exception)
            {
            }
            try
            {
                this.clientSocket.Close();
            }
            catch (Exception)
            {
            }
            this.connected = false;
            return res;
        }
        #endregion
        #region 数据接收
        /// <summary>
        /// 数据接受
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnReceive(object sender, SocketAsyncEventArgs e)
        {
            if (e.BytesTransferred == 0)
            {
                if (clientSocket.Connected)
                {
                    try
                    {
                        this.clientSocket.Shutdown(SocketShutdown.Both);
                    }
                    catch (Exception)
                    {
                    }
                    finally
                    {
                        if (this.clientSocket.Connected)
                        {
                            this.clientSocket.Close();
                        }
                    }
                }
                byte[] info = new Byte[] { 0 };
                this.OnMsgReceived(info, Flag);
            }
            else
            {
                byte[] buffer = new byte[e.BytesTransferred];
                Buffer.BlockCopy(e.Buffer, 0, buffer, 0, e.BytesTransferred);
                this.OnMsgReceived(buffer, Flag);
                Listen();
            }
        }
        #endregion
        #region 建立连接服务端的方法
        /// <summary>
        /// 建立连接的方法
        /// </summary>
        /// <returns></returns>
        public bool ConnectServer()
        {
            bool flag = false;
            this.StartListen += new StartListeHandler(SocketClient_StartListen);
            // this.OnMsgReceived += new ReceiveMsgHandler(SocketClient_OnMsgReceived);
            flag = this.Connect();
            if (!flag)
            {
                return flag;
            }
            return true;
        }
        #endregion
        #region 关闭与服务端之间的连接
        /// <summary>
        /// 关闭连接的方法
        /// </summary>
        /// <returns></returns>
        public int CloseLinkServer()
        {
            return this.Disconnect();
        }
        #endregion
        #region 监听方法
        /// <summary>
        /// 监听的方法
        /// </summary>
        private void SocketClient_StartListen()
        {
            this.Listen();
        }
        #endregion
        #region IDispose member
        public void Dispose()
        {
            if (this.clientSocket.Connected)
            {
                this.clientSocket.Close();
            }
        }
        #endregion
        #region 析构函数
        ~SocketClientAsync()
        {
            try
            {
                if (this.clientSocket.Connected)
                {
                    this.clientSocket.Close();
                }
            }
            catch
            {
            }
            finally
            {
            }
        }
        #endregion
    }
    #endregion

4、然后就是类的调用了

        //声明定义变量
        private SocketClientAsync ClientLink;//客户端连接对象
        private string Client_IP = "127.0.0.1";//服务端IP地址
        private int Client_Port = 12345;//服务端监听的端口号
        private Thread Client_Td;//通讯内部使用线程
        private bool ClientLinkRes = false;//服务器通讯状态标志
        private bool ThreadContinue = true;//线程轮询标志
        private bool isOnline = false;//是否在线标志
        /// <summary>
        /// 启动线程
        /// </summary>
        private void StartServer()
        {
            Client_Td = new Thread(LinkSocketSerFunc);
            Client_Td.Start();
        }
        /// <summary>
        /// 重连服务端线程
        /// </summary>
        private void LinkSocketSerFunc()
        {
            object lockobj = new object();
            int heartBeatCount = 0;
            ClientLink = new SocketClientAsync(Client_IP, Client_Port, 0);
            bool NotFirstIn = false;
            while (ThreadContinue)
            {
                try
                {
                    if (!ClientLinkRes)
                    {
                        isOnline = false;
                        if (NotFirstIn)
                        {
                            ClientLink.CloseLinkServer();
                            ClientLink = new SocketClientAsync(Client_IP, Client_Port, 0);
                        }
                        NotFirstIn = true;
                        ClientLink.OnMsgReceived += new SocketClientAsync.ReceiveMsgHandler(Client_OnMsgReceived);//绑定接受到服务端消息的事件
                        ClientLinkRes = ClientLink.ConnectServer();
                    }
                    else
                    {
                        //此处写通讯成功的逻辑处理
                    }
                }
                catch (Exception ex)
                {
                    ClientLinkRes = false;
                    System.Diagnostics.Debug.WriteLine(ex.ToString());
                }
                Thread.Sleep(1000);
            }
        }
        /// <summary>
        /// 接收消息处理
        /// </summary>
        /// <param name="info"></param>
        /// <param name="num"></param>
        private void Client_OnMsgReceived(byte[] info, int num)
        {
            try
            {
                ClientHeartBeat = 0;
                if (info.Length > 0 && info[0] != 0)//BCR连接错误NO
                {
                    //info为接受到服务器传过来的字节数组,需要进行什么样的逻辑处理在此书写便可                        
                }
                else
                {
                    ClientLinkRes = false;
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex.ToString());
            }
        }
        /// <summary>
        /// 终止服务
        /// </summary>
        public void StopServer()
        {
            if (ClientLinkRes)
            {
                ThreadContinue = false;
                ClientLink.CloseLinkServer();
                ClientLink.Dispose();
            }
        }

这基本的Socket客户端后台就写完了,可以直接复制使用,平时都是用这么去写Socket客户端,分享出来,大家就可以直接使用了!

C#Socket客户端异步实现

简易封装

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
namespace dclient
{
    public delegate void DelegateMsg(object msg);
    public class Client
    {
        private static Socket _clientSocket;
        private static string _server;
        private static int _port;
        public static DelegateMsg OnConnect;
        public static DelegateMsg OnSend;
        public static DelegateMsg OnReceive;
        public static DelegateMsg OnServerDown;
        public static DelegateMsg OnErr;
        public static void Connect()
        {
            try
            {
                _server = System.Configuration.ConfigurationManager.AppSettings["serverIp"];
                _port = int.Parse(System.Configuration.ConfigurationManager.AppSettings["serverPort"]);
                IPEndPoint ip = new IPEndPoint(IPAddress.Parse(_server), _port);
                _clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                _clientSocket.BeginConnect(ip, new AsyncCallback(ConnectCallBack), _clientSocket);
            }
            catch (Exception e)
            {
                throw e;
            }
        }
        private static void ConnectCallBack(IAsyncResult iar)
        {
            Socket client = (Socket)iar.AsyncState;
            try
            {
                client.EndConnect(iar);
                OnConnect("已连接");
            }
            catch (SocketException e)
            {
                if (e.ErrorCode == 10061)
                {
                    OnErr("服务器程序未运行或服务器端口未开放");
                }
                else
                {
                    OnErr(e.Message);
                }
            }
            finally
            {
            }
        }
        public static void Send(string msg)
        {
            if (_clientSocket == null || msg == string.Empty) return;
            msg += "\r\n";
            byte[] data = Encoding.UTF8.GetBytes(msg);
            try
            {
                _clientSocket.BeginSend(data, 0, data.Length, SocketFlags.None, asyncResult =>
                {
                    int length = _clientSocket.EndSend(asyncResult);
                    OnSend(string.Format("客户端发送消息:{0}", msg));
                }, null);
            }
            catch (Exception e)
            {
                OnErr(e.Message);
            }
        }
        public static void Recive()
        {
            byte[] data = new byte[1024];
            try
            {
                _clientSocket.BeginReceive(data, 0, data.Length, SocketFlags.None,
                asyncResult =>
                {
                    try
                    {
                        int length = _clientSocket.EndReceive(asyncResult);
                        OnReceive(string.Format("收到服务器消息:长度:{1},{0}", Encoding.UTF8.GetString(data), length));
                        Recive();
                    }
                    catch (SocketException e)
                    {
                        if (e.ErrorCode == 10054)
                        {
                            OnServerDown("服务器已断线");
                        }
                        else
                        {
                            OnErr(e.Message);
                        }
                    }
                }, null);
            }
            catch (Exception ex)
            {
                OnErr(ex.Message);
            }
        }
    }
}

使用

  public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            Client.OnConnect += new DelegateMsg(connect);
            Client.OnSend += new DelegateMsg(send);
            Client.OnReceive += new DelegateMsg(receive);
            Client.OnServerDown += new DelegateMsg(svrdown);
            Client.OnErr += new DelegateMsg(onerr);
        }
        private void Form1_Load(object sender, EventArgs e)
        {
            Client.Connect();
        }
        private void connect(object msg)
        {
            System.Diagnostics.Debug.WriteLine(msg.ToString());
            Client.Send("DALO 发送测试");
            Client.Recive();
        }
        private void send(object msg)
        {
            System.Diagnostics.Debug.WriteLine(msg.ToString());
        }
        private void receive(object msg)
        {
            System.Diagnostics.Debug.WriteLine(msg.ToString());
        }
        private void svrdown(object msg)
        {
            System.Diagnostics.Debug.WriteLine(msg.ToString());
        }
        private void onerr(object msg)
        {
            System.Diagnostics.Debug.WriteLine(msg.ToString());
        }
    }

未实现的几个常用操作

1、接收服务器发送的大数据量的合包。

2、服务器断线后客户端自动检测并重连,需先将_clientSocket释放。

3、心跳包。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

C#之Socket客户端全过程

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

C#之Socket客户端全过程

这篇文章主要介绍了C#之Socket客户端全过程,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
2023-05-19

Android编程之客户端通过socket与服务器通信的方法

本文实例讲述了Android编程之客户端通过socket与服务器通信的方法。分享给大家供大家参考,具体如下: 下面是一个demo,Android客户端通过socket与服务器通信。 由于Android里面可以完全使用java.io.*包和j
2022-06-06

C# winfroms使用socket客户端服务端的示例代码

本文介绍了如何在C#WinForms中使用Socket实现客户端-服务器通信。示例代码演示了客户端如何连接到服务器、发送和接收数据,以及服务器如何接收连接、发送和接收数据。本文适用于希望在C#WinForms应用程序中实现网络通信的开发人员。
C# winfroms使用socket客户端服务端的示例代码
2024-04-02

java 中怎么配置Socket多线程客户端

java 中怎么配置Socket多线程客户端,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。static class Sender implements Runn
2023-06-17

Python asyncore socket客户端开发基本使用教程

asyncore库是python的一个标准库,提供了以异步的方式写入套接字服务的客户端和服务器的基础结构,这篇文章主要介绍了Python asyncore socket客户端开发基本使用,需要的朋友可以参考下
2022-12-26

通过 Cgo 访问 aerospike C 客户端时出错

对于一个Golang开发者来说,牢固扎实的基础是十分重要的,编程网就来带大家一点点的掌握基础知识点。今天本篇文章带大家了解《通过 Cgo 访问 aerospike C 客户端时出错》,主要介绍了,希望对大家的知识积累有所帮助,快点收藏起来吧
通过 Cgo 访问 aerospike C 客户端时出错
2024-04-05

Python socket网络编程TCP/IP服务器与客户端通信

Python socket网络编程 初学 python,前段时间买了两本书《python 编程从入门到实践》《Python 核心编程第三版》,第一本书主要讲的是一些基本语法和一些基本的使用方法,而第二本则深入很多,自己看来也是一知半解,刚好
2022-06-04

Node.js查询MySQL并返回结果集给客户端的全过程

nodejs最大的优势也是大家用着最为难以理解的一点,就是它的异步功能,它几乎所有的io操作都是异步的,这也就导致很多人不理解也用不习惯,下面这篇文章主要给大家介绍了关于Node.js查询MySQL并返回结果集给客户端的相关资料,需要的朋友可以参考下
2022-12-27

Socket结合线程池怎么实现客户端和服务端通信demo

本篇内容主要讲解“Socket结合线程池怎么实现客户端和服务端通信demo”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Socket结合线程池怎么实现客户端和服务端通信demo”吧!1、要求可以
2023-06-29

Java编程Socket如何实现多个客户端连接同一个服务端

这篇文章主要介绍Java编程Socket如何实现多个客户端连接同一个服务端,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!Java Socket(套接字)通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄
2023-05-30

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录