我有个通讯.监听用的.我监听开启后。如果客户机与主机连接之后。。长时间不操作的话..我的监听就断掉了。监听不到客户机发送过来的数据不知道什么原因。我把源码发出来。请各位大哥帮帮忙谢谢using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;using System.Net;
using System.Net.Sockets;namespace Server
{
    public partial class Server2 : Form
    {
        delegate void MsgRef(string msg);
        public Server2()
        {
            InitializeComponent();
        }
        AsySocket listener = null;
        SortedList<string, AsySocket> clients = new SortedList<string, AsySocket>();
        private void button1_Click(object sender, EventArgs e)
        {
listener = new AsySocket(this.textBox1.Text, Int32.Parse(textBox2.Text));             
listener.OnAccept += new AcceptEventHandler(listener_OnAccept);//AcceptEventHandler 
            listener.Listen(10);            this.button1.Enabled = false;
        }
        void listener_OnAccept(AsySocket AcceptedSocket)         {                     //AsySocket异部传输的对象
                        AcceptedSocket.OnStringDataAccept += new StringDataAcceptHandler(AcceptedSocket_OnStringDataAccept);
            AcceptedSocket.OnClosed += new AsySocketClosedEventHandler(AcceptedSocket_OnClosed);
            AcceptedSocket.BeginAcceptData ;  
clients.Add(AcceptedSocket.ID, AcceptedSocket);
        }
        void AcceptedSocket_OnClosed(string SocketID, string ErrorMessage)
        {
            //客户端关闭
            clients.Remove(SocketID);
                   }        void AddMsg(string msg)
        {
            txtMsg.AppendText(Environment.NewLine + msg + Environment.NewLine);
        }        void AcceptedSocket_OnStringDataAccept(string AccepterID, string AcceptData)
        {
            try
            {
                 MsgRef m = new MsgRef(AddMsg);
                this.Invoke(m, new object[] { AcceptData });
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
            }
        }
        private void txtMsg_TextChanged(object sender, EventArgs e)
        {
            txtMsg.SelectionStart = txtMsg.Text.Length;
            if (txtMsg.Text.Length > 30000)
            {
                txtMsg.Text = "";
            }
        }
        private void button2_Click(object sender, EventArgs e)
        {
                     listener = new AsySocket(this.textBox4.Text, Int32.Parse(textBox3.Text));             listener.OnAccept += new AcceptEventHandler(listener_OnAccept);
            listener.Listen(10);            this.button2.Enabled = false;
        }    }
}
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace Server
{
        public delegate void StreamDataAcceptHandler(string AccepterID, byte[] AcceptData); 
        public delegate void StringDataAcceptHandler(string AccepterID, string AcceptData    public delegate void AcceptEventHandler(AsySocket AcceptedSocket);  
    public delegate void AsySocketClosedEventHandler(string SocketID,string ErrorMessage);
        public class StateObject     {
        // Client socket.
        public Socket workSocket = null;
        // Size of receive buffer.
        public const int BufferSize = 1024;
        // Receive buffer.6
        public byte[] buffer = new byte[BufferSize];
        // Received data string.
        public StringBuilder sb = new StringBuilder();
    }
        public class AsySocket
    {
               public AsySocket(string LocalIP, int LocalPort) //001
        {
            mSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);            try
            {
                IPAddress ip = Dns.GetHostAddresses(LocalIP)[0];
                IPEndPoint ipe = new IPEndPoint(ip, LocalPort);
                mID = Guid.NewGuid().ToString();  //创建一个唯一关键字。
                mSocket.Bind(ipe);//绑定要监听的IP跟端口到Socket
            }
            catch (Exception)
            {
                //ErrLog.RecordErr(e, ModuleName, "AsySocket", "");
            }
        }
               public AsySocket(Socket linkObject)          {
            mSocket = linkObject;
            mID = Guid.NewGuid().ToString();//创建唯一标识
        }
        #region 私有字段
        private Socket mSocket = null;
        string mID = "";
        private const string ModuleName = "GYGameServer.AsySocket";
        private StreamDataAcceptHandler onStreamData = null;
        private StringDataAcceptHandler onStringData = null;
        private AcceptEventHandler onAccept = null;
        private AsySocketClosedEventHandler onClosed = null;        #endregion        #region 公共属性
               public static string EndChar
        {
            get
            {
                return new string((char)0,1);
            }
        }
        public string ID   //08
        {
            get
            {
                return mID;
            }
        }
               public static char LastSign
        {
            get
            {
                return (char)0;
            }
        }
               public Socket LinkObject
        {
            get
            {
                return mSocket;
            }
            set
            {
                mSocket = value;
            }
        }
        #endregion        #region 公共方法
              public void Listen(int backlog)  //003
        {
            if (mSocket == null)
                throw new ArgumentNullException("连接不存在");
            mSocket.Listen(backlog);  //监听端口的最大连接数为十,..开始监听
            mSocket.BeginAccept(new AsyncCallback(AcceptCallBack), null);//异步  该方法里面可以取出对方IP
        }
               public void BeginAcceptData()   //06-07-06
        {
            if (mSocket == null)
                throw new ArgumentNullException("连接对象为空");
            //开始接收数据
            StateObject state = new StateObject();  //创建类对象
            state.workSocket = mSocket; 
            mSocket.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
            //receiveDone.WaitOne();
        }
 
        #endregion        #region 私有方法
        private void AcceptCallBack(IAsyncResult ar) //开始监听后调用    //01-03-01
        {
            Socket handler = mSocket.EndAccept(ar);
            string ip = ((IPEndPoint)handler.RemoteEndPoint).Address.ToString();  //监听到的对方的IP
            AsySocket NewSocket = new AsySocket(handler);//调用指定连接的构造方法
            //激发事件
            if (onAccept != null)
                onAccept(NewSocket);                      mSocket.BeginAccept(new AsyncCallback(AcceptCallBack), null);
        }
               private void ReceiveCallback(IAsyncResult ar) //0.1
        {
            try                       //IAsyncResult.AsyncState获取用户定义的对象,它限定或包含关于异步操作的信息。
            {
                //                            
                StateObject state = ar.AsyncState as StateObject;
                //读取数据
                int bytesRead = mSocket.EndReceive(ar); //数据的长度
                if (bytesRead > 0)
                {
                    state.sb.Append(UTF8Encoding.GetEncoding("GB2312").GetString(state.buffer, 0, bytesRead));
                    string sb = state.sb.ToString();
                   
                        //接收完成
                        //激发事件
                        if (onStreamData != null)
                            onStreamData(mID, UTF8Encoding.UTF8.GetBytes(sb));
                        if (onStringData != null)
                            onStringData(mID, sb);       //跳转到。。AcceptedSocket_OnStringDataAccept                         state = new StateObject(); //将接收的数据显示完之后。。又将StateObject()设置为初始状态
                        state.workSocket = mSocket;
                        
                    mSocket.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
                }
            }
            catch (SocketException se)
            {
                if (onClosed != null)
                    onClosed(ID,se.Message);
            }
            catch (Exception e)
            {
                throw new ApplicationException(e.Message);
            }        }              public event AsySocketClosedEventHandler OnClosed   //05
        {
            add
            {
                onClosed += value;
            }
            remove
            {
                onClosed -= value;
            }
        }
                public event AcceptEventHandler OnAccept  //002
        {
            add
            {
                onAccept += value;
                
            }
            remove
            {
                onAccept -= value;
            }
        }
             public event StreamDataAcceptHandler OnStreamDataAccept
        {
            add
            {
                this.onStreamData += value;
            }
            remove
            {
                this.onStreamData -= value;
            }
        }
             public event StringDataAcceptHandler OnStringDataAccept    //04-03
        {
            add
            {
                onStringData += value;
            }
            remove
            {
                onStringData -= value;
            }
        }
        #endregion
    }
}

解决方案 »

  1.   

    先做个心跳测试吧。每20-30秒发个包过来,看看到底是在什么时间断的,看看是不是因为长时间不操作导致系统注销了,所以程序不运行了。我没试过socket链接后,程序运行中而socket断了的情况。断掉通常都是因为客户端或者服务端的程序被ko掉了。
      

  2.   

    Implementation of Connecting a Socket with Timeout in C#
      

  3.   

    长时间不通讯就是会断开的,即使是tcp也是这样。需要心跳包维持连接。
      

  4.   

    我对Socket也不熟刚学的而已。。但是这问题上面的大哥能不能帮我搞定下..谢谢
      

  5.   

    或者客户端自己定时发一个数据包过来。在这么初学,你发一个数据包会发吧。弄一个Timer,每5分钟随便发一个字符串给服务端。
      

  6.   

    你代码太长了.我做过socket的软件可以联系我.
      

  7.   

    你对“监听”这个概念有严重的bug。我拿MySQL服务做个例子,假设一个企业网上有1500台电脑,平均每台电脑上有30个程序、300个线程可能要跟企业的一个MySQL服务通信,也就是说这个服务至少要服务企业内45万个客户端连接,难道一个客户端要连接服务之前先跑到服务端上的一个TextBox上去打入一个新的地址(Textbox1、Textbox2)并且按下一个按钮(button1)好让服务器启动在另一个socket端口来“监听”?我严重怀疑你能够写出服务程序。我建议你按照我提供的这个思路,好好想想一个服务器程序在一个端口来服务几十万可能的客户端应用程序连接时该如何编程吧。
      

  8.   

    网上的所谓socket“服务器”代码不要轻易抄袭,首先理解一下服务器的领域功能,你自己就可以看出网上那些仅仅能让你会几条socket语句但是绝对做不出实际产品的范例程序来。