2 qq 34725366 qq_34725366 于 2016.04.20 10:26 提问

远程主机强迫关闭了一个现有的连接,求助~
问题是发生在我的客户端和服务器端之间进行Modbus TCP通讯的时候。代码如下:
    internal class ModbusTcpIpWrapper : ModbusWrapper, IDisposable
    {

        public static ModbusTcpIpWrapper Instance = new ModbusTcpIpWrapper();
        private ModbusSocketWrapper socketWrapper = new ModbusSocketWrapper();
        public bool Connected = false;

        #region modbus tcp连接

        public override void Connect(string ip)
        {
            if (!Connected)
            {
                this.socketWrapper.Logger = Logger;
                this.socketWrapper.Connect(ip);
                this.Connected = true;
            }
        }

        #endregion

        #region 读取Modbus寄存器数据

        public override byte[] Receive(string ip, byte functionCode, UInt16 startAddress, short registerNum, int bufferSize)
        {
            Connect(ip);
            List<byte> sendData = new List<byte>(255); //申请一个255个字节空间的List

            //发送Modbus请求ADU编码
            sendData.AddRange(ModbusValueHelper.Instance.GetBytes(this.NextDataIndex())); //事务ID标识
            sendData.AddRange(new Byte[] { 0, 0 }); //Protocal Identifier(协议标识),Modbus中此值为0
            sendData.AddRange(ModbusValueHelper.Instance.GetBytes((short)6)); //后续的Byte数量(针对读请求,后续为6个byte)
            sendData.Add((byte)0); //Unit Identifier(单元标识符):用于系统间的路由
            sendData.Add((byte)functionCode); //读取寄存器中的值
            sendData.AddRange(ModbusValueHelper.Instance.GetBytes((Int16)startAddress)); //起始地址
            sendData.AddRange(ModbusValueHelper.Instance.GetBytes((short)registerNum)); //需要读取寄存器的数量
            this.socketWrapper.Write(sendData.ToArray()); //发送读请求

            //防止连续读写引起前台的UI线程堵塞
            Application.DoEvents();

            //读取Response Header:完后会返回8个byte的Response Header
            byte[] receiveData = socketWrapper.Read(bufferSize, ip); //缓冲区中的数量不超过256byte,一次读256byte,防止残余数据影响下次读取
            short identifier = (short)((((short)receiveData[0]) << 8) + receiveData[1]);

            //读取返回数据:根据Response Header,读取后续的数据
            if (identifier != CurrentDataIndex) //请求的数据标识与返回的标识不一致,则丢掉数据包
            {
                return new Byte[0];
            }
            byte length = receiveData[8]; //最后一个字节,记录寄存器中数据的Byte数
            byte[] result = new byte[length];
            Array.Copy(receiveData, 9, result, 0, length); //从指定的索引源开始,复制receiveData中的一系列数据到result中(从指定目标的索引开始)
            return result;
        }

        #endregion
     internal class ModbusSocketWrapper : IDisposable
    {

        private static int Port = Int32.Parse(ConfigurationManager.AppSettings["Port"]); //数据传输的端口号Port,Modbus TCP规定为502
        private static int Timeout = Int32.Parse(ConfigurationManager.AppSettings["SocketTimeout"]); //设置数据发送超时时间
        public IModbusLog Logger { get; set; }
        public Socket Socket = null;

        #region 建立Socket连接

        /// <summary>
        /// 创建一个基于TCP上的Socket
        /// 实现Socket端口复用
        /// 将服务器主机的IP地址与端口号组合
        /// 建立与远程主机的连接
        /// </summary>
        public void Connect(string ip)
        {
            this.Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            this.Socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, Timeout);
            IPEndPoint ipConnect = new IPEndPoint(IPAddress.Parse(ip), Port);
            this.Socket.Connect(ipConnect);
        }

        #endregion

        #region 读取数据

        public byte[] Read(int length, string ipGet)
        {
            byte[] data = new byte[length];
            //while (true)
            //{
                try
                {
                    Socket.Receive(data);
                    Log("Receive:", data);
                    return data;
                }
                catch (Exception ex)
                {
                    string ep = ex.ToString();
                    Socket.Close();
                    Connect(ipGet);
                    //MessageBox.Show(ep);
                    return null;
                }
            //}
        }

        #endregion

        #region 写入数据

        public void Write(byte[] data)
        {
            try
            {
                Log("Send:", data);
                Socket.Send(data);
            }
            catch (Exception ex)
            {
                string ep = ex.ToString();
                //MessageBox.Show(ep);
            }
        }

        #endregion

        #region 记录数据

        public void Log(string type, byte[] data)
        {
            if (Logger != null)
            {
                //创建一个新的可变字符字符串对象
                StringBuilder logText = new StringBuilder(type);
                //将数据中的每一个byte量
                foreach (byte item in data)
                {
                    //将括号内的item转化成字符串表示形式添加到当前对象表示的字符串结尾处
                    logText.Append(item.ToString() + "");
                }
                Logger.Write(logText.ToString());
            }
        }

        #endregion

        #region IDisponsable 成员

        public void Dispose()
        {
            if (Socket != null)
            {
                Socket.Close();
            }
        }

        #endregion

    }
 当我运行时,就会出现下面的问题

图片说明
图片说明
我将我发送的请求和Modbuspull这个工具发送的请求进行了对比,是一样的,但是我的请求会被拒绝,而Modbuspull这个工具发送的请求能正常收到请求后服务器返回的数据,请问这个原因是什么?

1个回答

CSDNXIAON
CSDNXIAON   2016.04.20 10:33

真机调试,远程主机强迫关闭了一个现有的连接
Adb connection Error:远程主机强迫关闭了一个现有的连接
Adb connection Error:远程主机强迫关闭了一个现有的连接。
----------------------同志你好,我是CSDN问答机器人小N,奉组织之命为你提供参考答案,编程尚未成功,同志仍需努力!

Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!
其他相关推荐
python socket.error: [Errno 10054] 远程主机强迫关闭了一个现有的连接。问题解决方案
python socket.error: [Errno 10054] 远程主机强迫关闭了一个现有的连接。问题解决方案:前几天使用python读取网页。因为对一个网站大量的使用urlopen操作,所以会被那个网站认定为攻击行为。有时就不再允许下载。导致urlopen()后,request.read()一直卡死在那里。最后会抛出errno 10054.这个错误是conn...
远程主机强迫关闭了一个现有的连接。请高手解答?
-
tcp nio 远程主机强迫关闭了一个现有的连接
package server; import java.io.IOException; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.net.SocketAddress; import java.nio.ByteBuffer; import java.nio.channels.Selecti
解决 Android 远程主机强迫关闭了一个现有的连接
在windows平台下用eclipse 开发android 程序,adb 常报以下的错误: [2015-05-08 10:16:49 - DeviceMonitor] Connection attempts: 8 [2015-05-08 10:16:55 - DeviceMonitor] Adb connection Error:远程主机强迫关闭了一个现有的连接。 [2015-05-08 1
“Adb connection Error:远程主机强迫关闭了一个现有的连接。”的解决方法
我在用eclipse时,用手机调试软件,Devices里面不显示我的手机, 控制台一直发送 “Adb connection Error:远程主机强迫关闭了一个现有的连接。” 网上说了需多方法,比如说,直接点击reset adb,或者用命令行方式重启 adb等等, 但这些方法都忽略了一个前提,就是你的手机是最近买的还是已经用了一两年。不多说,直接看我的解决方法: 第一种方法:
经验总结-DDMS出现:远程主机强迫关闭了一个现有的连接的解决办法
几年前成为一个程序员,服务器、前端、Android都有涉及,并首先专攻Android开发,目标是成为一个杰出的互联网开发者,为人类的便捷生活做出贡献。刚开始学习Android开发的时候,是用eclipse,android studio还没有普及,学习过程中也遇到了很多问题,所以想把遇到的问题写成博客,和大家一起分享,同时我也可以用博客记录编程生涯的点点滴滴。刚开始规划的时候,热情满满,开始了我的第
python 远程主机强迫关闭了一个现有的连接 socket 超时设置 errno 10054
python 远程主机强迫关闭了一个现有的连接 socket 超时设置 errno 10054 转自: http://blog.csdn.net/cctt_1/article/details/4512103 python socket.error: [Errno
解决一个远程主机强迫关闭连接的bug
摘要 本文描述了如何解决一个rpc调用发生的问题,旨在提供一种解决思路,而不是一个具体的问题解决方案 问题描述 通过dubbo调用一个API时,间歇性的出现远程主机强迫关闭连接的问题 java.io.IOException: 远程主机强迫关闭了一个现有的连接。 at sun.nio.ch.SocketDispatcher.read0(Native Method)
UDP 远程主机强迫关闭了一个现有的连接
在UDP通信过程中,如果客户端中途断开,服务器会收到一个SocketException,错误ID为10054,描述是“远程主机强迫关闭了一个现有的连接”,紧接着的事就可怕了,UDP服务终止监听,所有客户端都受到了影响。也就是说一个客户端引起的异常导致了整个系统的崩溃。   找了好几天了。终于找到了解决办法。   在初始化对象后设置属性如下:                    
WindowsFormsApplicationBase 遇 Remoting 报 远程主机强迫关闭了一个现有的连接
近日软件增加了通过远程对象调用远程对象的方法功能,在我的开发环境很顺利,按部就班完成了调用,测试也顺利通过。但发布到用户电脑上就出现了问题,不是所有电脑都有问题,个别电脑出现了如下错误:远程主机强迫关闭了一个现有的连接,把堆栈输出: 在 System.Net.Security.NegoState.ProcessAuthentication(LazyAsyncResult lazyResult)