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 memberpublic 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客户端相关推荐

  1. python客户端和服务端区别_Python socket 客户端和服务器端

    connection, address = socket.accept() 调 用accept方法时,socket会时入"waiting"状态.客户请求连接时,方法建立连接并返回服 ...

  2. Android:Socket客户端开发,Android 的Socket客户端优化,Android非UI线程修改控件程序崩溃的问题

    一.Android:Socket客户端开发 创建一个工程 我们要做的是按下按键之后,去往服务器 (服务器) 或者我们自己写的服务器 ,给他发送一些预定好的东西 然后打开操作界面 然后修改一下 你要发送 ...

  3. Java:socket服务端,socket服务端支持多连接,socket客户端,socket客户端支持发送和接受

    一.Java之socket服务端 新建一个Java工程 命名 给他先创建一个类 在类里面我们做一个main 这里面也需要,创建套接字,IP号,端口号 但是java中有一个类         Serve ...

  4. 31 socket客户端. 服务器 异常 语法

    Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口. 基于文件类型的套接字家族 套接字家族的名字:AF_UNIX unix一切皆文件,基于文件的套接字调用的就是底层的文件系统来 ...

  5. rudesocket如何使用_c++ socket 客户端库 socks5 客户端 RudeSocket™ Open Source C++ Socket Library...

    介绍 一个c++ socket 客户端库 The RudeSocket™ Open Source C++ Socket Library provides a simple to use interfa ...

  6. C# Socket客户端采用双线程断网重连断线重连)

    C# Socket客户端采用双线程断网重连断线重连 2021年07月15日 13:38:18更新 C# Socket服务端 双线程断网重连断线重连 C# Socket客户端采用双线程断网重连断线重连 ...

  7. QT 中Socket客户端与服务器异常断开后重连

    在现在的项目开发中,经常要使用TCP/IP协议来进行通讯,但有时候与服务器端的链接由于网络问题导致连接异常或断开,这就需要我们的软件能自动重连,在Linux中,我们的思维一般是通过心跳包来监控连接是否 ...

  8. Netty服务器部署在Android设备上,接收来自PC客户端的Java Socket客户端发送的JSON数据

    Netty服务器部署在Android设备上,接收来自PC客户端的Java Socket客户端发送的数据 一个简单的模型,在Android手机上部署一个Netty写的服务器,绑定端口9000,等待客户端 ...

  9. php 客户端socket长连接超时,[PHP] socket客户端时的超时问题

    连接socket分为连接超时和读取超时 $sock=stream_socket_client("www.google.com:80", $errno,$errstr,2);    ...

  10. python客户端和服务端实验_python实现socket客户端和服务端简单示例

    复制代码@H_301_3@ 代码如下: import socket #socket通信客户端 def client(): mysocket=socket.socket(socket.AF_INET,s ...

最新文章

  1. 线程技术 ☞ Future模式
  2. Windows 下启动前删除Resin日志等文件的bat命令
  3. 二叉树、二叉排序树及其遍历
  4. 如何不使用Java 8默认方法
  5. 【PAT甲级 - 1028】List Sorting (25分)(模拟,排序)
  6. (33)Verilog HDL缩减运算
  7. 人类与AI结合的最佳形态是什么样?
  8. android 抓包 2
  9. 西门子plc烧录单片机_单片机可以替代 PLC 吗?
  10. CAD工具——批量打印
  11. 西安交大计算机研究生拟录取,西安交通大学2018硕士研究生拟录取名单公示
  12. GprMax2D ——ABC(吸收边界条件)相关命令
  13. 专题:手把手学习硬件基础------10、常用器件
  14. 敏捷项目管理的五个要素
  15. JUC-05-ForkJoin,Future(了解即可)
  16. PTA L2-039 清点代码库
  17. Linux网络新技术基石:eBPF and XDP
  18. 免费瘫软入院,付费发飙成壮汉,YoMail 想干嘛?
  19. scratch变量讲解1
  20. 英文学习20180321

热门文章

  1. vue脚手架安装 axios 安装 配置 轮播图
  2. C++程序设计语言(特别版)pdf
  3. 人口各省预测模型matlab_流体力学/医学学科交叉:感染人口预测模型
  4. 设置smtp服务器信息,SMTP服务器设置(IIS6.0)
  5. 43 RBF神经网络
  6. 开源库uthash第一弹uthash.h
  7. 从零开始构建嵌入式实时操作系统1——任务切换
  8. C程序设计语言(KR)笔记
  9. windows server2016 如何安装IIS
  10. 2020软件设计师考试大纲