C# Socket之异步TCP客户端断线重连

  我们知道TCP通信是一种面向连接的Socket,针对于面向连接的TCP服务应用,安全,但是效率低,它首先需要服务端开启服务,然后客户端才可以去连接,如果服务端没有开启通信服务或者连接之后再中途因为某些原因断开连接了,那么都是会通信失败的,所以我们这篇博客主要是对TCP通信加入两个机制。1,客户端开启后未连接成功,自动重连请求 2,若通信途中因为某些原因断开连接了自动重连机制  因为测试发现如果是程序运行途中我们利用同步的方式重新连接的话连接时会出现程序卡顿的情况,这个对用户的体验是非常不好的,为了避免这个情况,我们采用的是异步TCP通信的方式,代码如下,这是一个单例脚本,无需挂载,程序开始时调用一下ConnectServer方法开启通信就好,记得关闭程序时要调用一下Close方法来断开挂起的异步连接,否则调试的时候通信会一直保存着。

/***********************************
*    Description:异步TCP客户端
*    Mountpoint:这是一个单例脚本,无需挂载,直接调用即可
*    Date:2019.06.25
*    Version:unity版本2017.2.0f3
*    Author:LJF
***********************************/
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Net;
using System.Net.Sockets;
using System;
using System.Text;

namespace LJF
{
    //规范命名、添加注释、合理封装、限制访问权限
    public class AsyncTcpClient
    {
        private string ip1;
        private int port1;
        byte[] ReadBytes = new byte[1024 * 1024];
        //单例
        public static AsyncTcpClient Instance
        {
            get
            {
                if (instance==null)
                {
                    instance = new AsyncTcpClient();
                }
                return instance;
            }
        }
        private static AsyncTcpClient instance;

        System.Net.Sockets.TcpClient tcpClient;

        //连接服务器
        public void ConnectServer(string ip, int port)
        {
            //Debuger.EnableSave = true;
            ip1 = ip;
            port1 = port;
            try
            {
                tcpClient = new System.Net.Sockets.TcpClient();//构造Socket
                tcpClient.BeginConnect(IPAddress.Parse(ip), port,Lianjie, null);//开始异步
            }
            catch (Exception e)
            {
                Debug.Log(e.Message);
            }
        }

        //连接判断
        void Lianjie(IAsyncResult ar)
        {
            if (!tcpClient.Connected)
            {
                Debug.Log("服务器未开启,尝试重连。。。。。。");
                tcpClient.BeginConnect(IPAddress.Parse(ip1), port1, Lianjie, null);
                //IAsyncResult rest = tcpClient.BeginConnect(IPAddress.Parse(ip1), port1, Lianjie, null);
                //bool scu= rest.AsyncWaitHandle.WaitOne(3000);
            }
            else
            {
                Debug.Log("连接上了");
                tcpClient.EndConnect(ar);//结束异步连接
                tcpClient.GetStream().BeginRead(ReadBytes, 0, ReadBytes.Length, ReceiveCallBack, null);
            }
        }

        //接收消息
        void ReceiveCallBack(IAsyncResult ar)
        {
            try
            {
                int len = tcpClient.GetStream().EndRead(ar);//结束异步读取
                if (len > 0)
                {

                    string str = Encoding.UTF8.GetString(ReadBytes, 0,len);
                    str = Uri.UnescapeDataString(str);
                    //将接收到的消息写入日志
                    //Debuger.Log(string.Format("收到主机:{0}发来的消息|{1}", ip1, str));
                    //Debug.Log(str);
                    tcpClient.GetStream().BeginRead(ReadBytes, 0, ReadBytes.Length, ReceiveCallBack, null);
                }
                else
                {
                    tcpClient = null;
                    Debug.Log("连接断开,尝试重连。。。。。。");
                    ConnectServer(ip1,port1);
                }
            }
            catch (Exception e)
            {
                Debug.Log(e.Message);
            }
        }

        //发送消息
        public void SendMsg(string msg)
        {
            byte[] msgBytes = Encoding.UTF8.GetBytes(msg);
            tcpClient.GetStream().BeginWrite(msgBytes, 0, msgBytes.Length, (ar) => {
                tcpClient.GetStream().EndWrite(ar);//结束异步发送
            }, null);//开始异步发送
        }

        /// <summary>
        /// 断开连接
        /// </summary>
        public void Close()
        {
            if (tcpClient != null && tcpClient.Client.Connected)
                tcpClient.Close();
            if (!tcpClient.Client.Connected)
            {
                tcpClient.Close();//断开挂起的异步连接
            }
        }

    }
}

原文地址:https://www.cnblogs.com/linkshow/p/12100929.html

时间: 2024-10-01 23:49:03

C# Socket之异步TCP客户端断线重连的相关文章

【c#源码】基于TCP通信的客户端断线重连

源码下载 在CS程序中,断线重连应该是一个常见的功能. 此处的断线重连主要指的是服务器端因为某种故障,服务器端程序或者系统进行了重新启动,客户端能够自动探测到服务器端掉线,并尝试重新进行连接 本程序基于来自英国的开源c#通信框架的networkcomms(2.3.1版本) 先看一下效果 初始状态: 当服务器端程序关闭后,客户端会自动探测到,并在客户端显示相关信息 然后,我们设定为每隔5秒重连一次,可以自定义设置重连的次数,比如说重连50次,如果还没有重连成功,则放弃重连 然后我们重新启动服务器端

基于TCP通信的客户端断线重连

转载:http://www.cnblogs.com/networkcomms/p/4304362.html 源码下载 在CS程序中,断线重连应该是一个常见的功能. 此处的断线重连主要指的是服务器端因为某种故障,服务器端程序或者系统进行了重新启动,客户端能够自动探测到服务器端掉线,并尝试重新进行连接 本程序基于来自英国的开源c#通信框架的networkcomms(2.3.1版本) 先看一下效果 初始状态: 当服务器端程序关闭后,客户端会自动探测到,并在客户端显示相关信息 然后,我们设定为每隔5秒重

Netty 客户端断线重连

client 关闭后会执行 finally 代码块,可以在这里可以进行重连操作 public class NettyClient implements Runnable { private final String host; private final int port; private final int reconnectSleepSeconds; public NettyClient(String host, int port, int reconnectSleepSeconds){ t

Windows Socket 编程:TCP客户端

#include <stdio.h> #include <stdlib.h> #include <winsock2.h> int main(int argc,char * argv[]) { char message[30]; WSADATA wsaData; SOCKET hSocket; SOCKADDR_IN servAddr; WSAStartup(MAKEWORD(2,2),&wsaData); hSocket = socket(PF_INET,SOC

关于socket tcp 断线重连

这个问题困扰过我几次,都没有来得及研究,今天研究一下. 首先写一个最简易的socket tcp程序,连接成功后再关闭服务器然后再用客户端各种操作看是什么情况 测试表明 (1)客户端已经连接,当服务端关闭程序时,客户端调用send函数发送失败,WSAGetLastError() 返回10054(远程主机强迫关闭了一个现有的连接) (2)客户端已经连接,当客户端关闭程序时,服务端调用recv函数接收失败,WSAGetLastError() 返回10054(远程主机强迫关闭了一个现有的连接) ,这时对

socket 断线重连

send发送数据时,发送失败,进行如下重连处理: if(send(sockfd, serbuf, readlen, 0) < 0)//serbuf中有数据可以发送才会执行这条语句 { printf("serial to tcp send msg error: %s(errno: %d)\n", strerror(errno), errno);//服务端断掉,则发送失败. //exit(0); //断线重连 sleep(3); close(sockfd); sockfd = soc

基于C#的socket编程的TCP异步实现

一.摘要 本篇博文阐述基于TCP通信协议的异步实现. 二.实验平台 Visual Studio 2010 三.异步通信实现原理及常用方法 3.1 建立连接 在同步模式中,在服务器上使用Accept方法接入连接请求,而在客户端则使用Connect方法来连接服务器.相对地,在异步模式下,服务器可以使用BeginAccept方法和EndAccept方法来完成连接到客户端的任务,在客户端则通过BeginConnect方法和EndConnect方法来实现与服务器的连接. BeginAccept在异步方式下

Socket 通信原理(Android客户端和服务器以TCP&amp;&amp;UDP方式互通)

ZERO.前言 有关通信原理内容是在网上或百科整理得到,代码部分为本人所写,如果不当,还望指教. 一.Socket通信简介 Android与服务器的通信方式主要有两种,一是Http通信,一是Socket通信.两者的最大差异在于,http连接使用的是“请求—响应方式”,即在请求时建立连接通道,当客户端向服务器发送请求后,服务器端才能向客户端返回数据.而Socket通信则是在双方建立起连接后就可以直接进行数据的传输,在连接时可实现信息的主动推送,而不需要每次由客户端想服务器发送请求. 那么,什么是s

python socket模块:TCP,UDP客户端

__author__ = 'Administrator' import socket # tcp客户端 target_host = 'www.51cto.com' target_port = 80 # AF_INET是标准IPv4地址或主机名,SOCK_STREAM表示是TCP的方式 client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 建立连接 client.connect((target_host, target_port)