异步接受客户端断点执行问题

啾啾我 2016-08-29 03:20:10

IPEndPoint ipe = new IPEndPoint(SvrIp, SvrPort);
//在服务器端创建一个负责监IP地址跟端口号的Socket
_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

//监听
_socket.Bind(ipe);
_socket.Listen(50);

//设置异步方法接受客户端连接
_socket.BeginAccept(new AsyncCallback(Listen), _socket);


void Listen(IAsyncResult ar)
{
try
{
//获取用户定义的对象,它限定或包含关于异步操作的信息。
Socket listener = (Socket)ar.AsyncState;
//异步接受传入的连接尝试,并创建新的 Socket 来处理远程主机通信。
Socket client = listener.EndAccept(ar);

SocketClient state;
//SId默认为值为100,Uid默认值为10001
if (Sid > 0 && Sid < 10000)
state = new SocketClient(Sid, client);
else
{
//我断点在这里
Uid = Uid + 1;
state = new SocketClient(Uid, client);
}

if (Sid > 0 && Sid < 10000)//说明是服务端,记录登录状态
{
Sid = -1;//服务端Id只允许使用1次
}

//继续接受客户端
_socket.BeginAccept(new AsyncCallback(Listen), _socket);
}


问题:我断点到Uid = Uid + 1;这个位置,第一次执行,ff浏览器不会执行到我断点的地方,然后ie6、7、8、9浏览器确能够执行到我断点的地方,我异步接收客户端连接,正常是执行不到断点的位置,不知道为什么,我代码有问题吗?求解!
...全文
365 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
啾啾我 2016-08-30
  • 打赏
  • 举报
回复
flash socket理论知识没有掌握,不过还是谢谢各位。
Poopaye 2016-08-30
  • 打赏
  • 举报
回复
引用 16 楼 sossos555 的回复:
[quote=引用 15 楼 shingoscar 的回复:] 还是连2次,第二次连Listen都进不了?
只连接1次的情况下,ff浏览器不会到我断点的位置,而ie浏览器会执行到我断点的位置,我做了记录在同样连接一次的情况下记录如下: 我用ie8浏览器,记录了一下sid和uid结果是 Sid:100 Uid:10000 Sid:-1 Uid:10001 我用ff浏览器测试,记录了一下sid和uid结果是 Sid:100 Uid:10000 问题,同样的程序,怎么不同的浏览器执行不一样呢?感觉代码哪个地方有问题,就是没有找到,求大神看看是怎么回事。[/quote] 那就很显然了,ie发起了两次connect,你可以看下你客户端的代码,或者抓个包试试
啾啾我 2016-08-30
  • 打赏
  • 举报
回复
引用 17 楼 diaodiaop 的回复:
实在不懂 服务端为什么要new 一个socketClient....
SocketClient是个类,专门进行处理收发消息用的。这个应该不影响吧。
by_封爱 2016-08-30
  • 打赏
  • 举报
回复
实在不懂 服务端为什么要new 一个socketClient....
啾啾我 2016-08-30
  • 打赏
  • 举报
回复
引用 15 楼 shingoscar 的回复:
还是连2次,第二次连Listen都进不了?
只连接1次的情况下,ff浏览器不会到我断点的位置,而ie浏览器会执行到我断点的位置,我做了记录在同样连接一次的情况下记录如下: 我用ie8浏览器,记录了一下sid和uid结果是 Sid:100 Uid:10000 Sid:-1 Uid:10001 我用ff浏览器测试,记录了一下sid和uid结果是 Sid:100 Uid:10000 问题,同样的程序,怎么不同的浏览器执行不一样呢?感觉代码哪个地方有问题,就是没有找到,求大神看看是怎么回事。
Poopaye 2016-08-29
  • 打赏
  • 举报
回复
还是连2次,第二次连Listen都进不了?
Poopaye 2016-08-29
  • 打赏
  • 举报
回复
那你到底什么问题啦 ff连接2次到不了断点,意思就是每次都是sid=100?
啾啾我 2016-08-29
  • 打赏
  • 举报
回复
引用 12 楼 shingoscar 的回复:
就是你没发送数据啊
什么意思,我断点client.EndReceive(ar)是有数据的啊
Poopaye 2016-08-29
  • 打赏
  • 举报
回复
就是你没发送数据啊
啾啾我 2016-08-29
  • 打赏
  • 举报
回复
引用 10 楼 shingoscar 的回复:
sid默认是0,第一次连接肯定是Uid = Uid + 1; 估计你是先用ie测试,再用ff测试,当中又没重新创建对象 如果断点不到,那加个日志看看
我SocketListen.Sid=100,这个我先进行了赋值,然后在Start()的,而且我每次调试都是发布后重新启动调试 补充一下上面的改成 private ManualResetEvent LoginValidataDone = new ManualResetEvent(false); 是不是我LoginValidataDone 线程这块有问题啊
Poopaye 2016-08-29
  • 打赏
  • 举报
回复
sid默认是0,第一次连接肯定是Uid = Uid + 1; 估计你是先用ie测试,再用ff测试,当中又没重新创建对象 如果断点不到,那加个日志看看
啾啾我 2016-08-29
  • 打赏
  • 举报
回复
引用 2 楼 sp1234 的回复:
你认为的“第一次执行”是你的感觉,你有记录能看出实际收到了几次请求吗?
代码已经全部贴出来了,麻烦大神看一下,估计是LoginValidataDone这块有问题。
啾啾我 2016-08-29
  • 打赏
  • 举报
回复

using System.Net.Sockets;
using System.Text;
using System;
using System.Threading;
using System.Web.Script.Serialization;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Net;


namespace Msg
{
    /// <summary>
    /// 处理每一个连接的客户
    /// </summary>
    public class SocketClient
    {
        #region === 私有变量 ===
        /// <summary>
        /// 客户端SOCKET
        /// </summary>
        private Socket _workSocket = null;
        private int _uid;
        private string _userName;
        private const int DefaultBufferSize = 1024 * 2;
        private byte[] buffer;

        public event EventHandler<ChatEventArgs> ChatEvent;

        #endregion

        
        #region === 公开属性 ===
        /// <summary>
        /// 客户端ID
        /// </summary>
        public int Uid
        {           
            get { return _uid; }
            set { _uid = value; }
        }

        public string UserName 
        {            
            get { return _userName; }
            set { _userName = value; }
        }

        #endregion
        

        #region === 构造函数 ===

        /// <summary>
        /// 构造函数
        /// </summary>
        public SocketClient(int id, Socket socket)
        {
            this._workSocket = socket;
            this.Uid = id;
            this.UserName = Common.IpAds(Common.GetIP());
            buffer = new byte[DefaultBufferSize];
        }

        #endregion


        #region === 开启独自数据处理 ===

        /// <summary>
        /// 开启独自数据处理
        /// </summary>
        public void Start()
        {
            try
            {
                byte[] inValue = new byte[] { 1, 0, 0, 0, 0x20, 0x4e, 0, 0, 0xd0, 0x07, 0, 0 }; //首次探测时间20 秒, 间隔侦测时间2 秒
                //byte[] inValue = new byte[] { 1, 0, 0, 0, 0x88, 0x13, 0, 0, 0xd0, 0x07, 0, 0 };// 首次探测时间5 秒, 间隔侦测时间2 秒
                _workSocket.IOControl(IOControlCode.KeepAliveValues, inValue, null);
            }
            catch { return; }
            //开始接受来自该客户端的数据 
            _workSocket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, 
                new AsyncCallback(ReceiveMessage), this);           
        }

        /// <summary>
        /// 断开与客户端的连接
        /// </summary>
        public void Shutdown()
        {
            try
            {
                _workSocket.Shutdown(SocketShutdown.Both);
                _workSocket.Close();
            }
            catch { }
        }
        #endregion


        #region === 接受客户端建立连接后的处理线程 ===      
  
      void ReceiveMessage(IAsyncResult ar)
        {
            try
            {
                SocketClient state = (SocketClient)ar.AsyncState;
                Socket client = state._workSocket;

                //登录成功,则进入消息等待中
                int BytesRead = 0;
                if (client.Connected)
                {
                    try
                    { BytesRead = client.EndReceive(ar); }
                    catch
                    {
                        Console.WriteLine("发生异常错误");
                        return;
                    }
                    if (BytesRead == 0)
                    {
                        Console.WriteLine("没有消息需要处理");
                        return;
                    }

                    //格式化帧头
                    DataDecrypt dd = new DataDecrypt(buffer);
                    string msg = dd.AnalyticData(buffer, dd.Length);
                    //处理消息
                }
                //继续接收来自来客户端的数据 
                client.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveMessage), state);
            }
            catch { }
        }

        #endregion


        #region === 把消息发送到对应的客户端 ===
        
        public void Send(ChatEventArgs o)
        {
            try
            {              
                byte[] bt = DataDecrypt.PackData("{" + o.ToString() + "}");
                _workSocket.Send(bt);
                Thread.Sleep(20);
            }
            catch { }           
        }

        /// <summary>
        /// 往关联的客户端发送数据
        /// </summary>
        public void Response(string message)
        {
            _workSocket.Send(Encoding.UTF8.GetBytes(message));
        }
        #endregion
    }
    
}
啾啾我 2016-08-29
  • 打赏
  • 举报
回复

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Threading;
using System.Net.Sockets;
using System.Collections;
using System.Web.Script.Serialization;
using System.Web;
using System.IO;
using System.Xml;
using Msg.Main;
using System.Media;


namespace Msg
{
    public class SocketListen
    {
        private IPAddress _ip;//绑定的IP地址
        private int _port; //使用的端口        
        public static Hashtable _clientList = null;//客户端列表  
        private Socket _socket = null;//用于侦听的Socket套接字
        private byte[] buffer = new byte[1024 * 2];
        private bool _run = false; //运行中
        private static int _uid = 10000;//新分配给客户端的Id    > 10000
        private static int _sid = 0;//主要记录服务器自定义的id   < 10000

        private ManualResetEvent LoginValidataDone = new ManualResetEvent(true);
        private ManualResetEvent sendDone = new ManualResetEvent(true);


        /// <summary>
        /// 客服Id
        /// </summary>
        public static int Sid
        {
            get { return _sid; }
            set { _sid = value; }
        }

        /// <summary>
        /// 客户端Id
        /// </summary>
        public static int Uid
        {
            get { return _uid; }
            set { _uid = value; }
        }

        #region === 开始监听 ===
        /// <summary>
        /// 开始侦听
        /// </summary>
        public bool Start()
        {           
            try
            {
                //创建端口号对象
                IPEndPoint ipe = new IPEndPoint(SvrIp, SvrPort);
                //在服务器端创建一个负责监IP地址跟端口号的Socket
                _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                
                //监听
                _socket.Bind(ipe);
                _socket.Listen(50);

                //设置异步方法接受客户端连接 
                _socket.BeginAccept(new AsyncCallback(Listen), _socket);
                _run = true;
                return true;
            }
            catch (Exception)
            {
                _run = false;
                return false;
            }
        }
        #endregion

        

        #region === 等待客户端的连接 ===
        /// <summary>
        /// 等待客户端的连接
        /// </summary>
        /// <param name="ar"></param>
        void Listen(IAsyncResult ar)
        {
            try
            {
                //如果服务器停止了服务,就不能再接收新的客户端 
                if (!_run)
                    return;

                //获取用户定义的对象,它限定或包含关于异步操作的信息。
                Socket listener = (Socket)ar.AsyncState;
                //异步接受传入的连接尝试,并创建新的 Socket 来处理远程主机通信。
                Socket client = listener.EndAccept(ar);

                //服务端可以自定义ID
                SocketClient state;
                if (Sid >= 0 && Sid < 10000)
                    state = new SocketClient(Sid, client);
                else
                {
                    Uid = Uid + 1;
                    state = new SocketClient(Uid, client);
                }                               
                state.ChatEvent += new EventHandler<ChatEventArgs>(State_ChatEvent);

                //登录认证,只有等ReceiveLoginValidateCallback执行完后才会继续
                LoginValidataDone.Reset();
                client.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveLoginValidateCallback), ar);
                LoginValidataDone.WaitOne();
                
                Agreement agr = new Agreement(Encoding.UTF8.GetString(buffer, 0, buffer.Length));
                if (agr.GetValue("swfobject") == "true")//(agr.Response。ToString().IndexOf("<policy-file-request/>") >= 0)
                {
                    string xml = "<?xml version=\"1.0\"?><cross-domain-policy><allow-access-from domain=\"*\" to-ports=\"*\" /></cross-domain-policy>\0";
                    state.Response(xml);//向客户端发送策略文件
                }           
                else
                    state.Response(agr.Response); //服务器作出握手回应        
                       
                //开启独自异步接收消息数据
                state.Start();              

                //将客户端信息置于列表中
                if (_clientList.ContainsKey(state.Uid))
                    _clientList.Remove(state.Uid);
                _clientList.Add(state.Uid, state);
                               
                if (Sid > 0 && Sid < 10000)//说明是服务端,记录登录状态
                {
                    Common.Record(Sid, true);
                    Sid = -1;//服务端Id只允许使用1次
                }

                //继续接受客户端 
                _socket.BeginAccept(new AsyncCallback(Listen), _socket);
            }
            catch (Exception)
            {
                //设置异步方法接受客户端连接 
                _socket.BeginAccept(new AsyncCallback(Listen), _socket);
            }
        }
        #endregion


        #region === 接收处理相关消息 ====
        /// <summary>
        /// 接收处理相关消息
        /// </summary>
        /// <param name="sender">socket对象</param>
        /// <param name="e">消息参数</param>
        void State_ChatEvent(object sender, ChatEventArgs e)
        {
            SocketClient sc = (SocketClient)sender;
            sc.Send(e);
        }

        private void ReceiveLoginValidateCallback(IAsyncResult ar)
        {
            try
            {
                Socket client = (Socket)ar.AsyncState;
                client.EndReceive(ar);                
                LoginValidataDone.Set();
            }
            catch
            {
                LoginValidataDone.Set();
            }
        }
        #endregion
  • 打赏
  • 举报
回复
引用 3 楼 sossos555 的回复:
[quote=引用 2 楼 sp1234 的回复:] 你认为的“第一次执行”是你的感觉,你有记录能看出实际收到了几次请求吗?
我用ie8浏览器,记录了一下sid和uid结果是 Sid:100 Uid:10000 Sid:-1 Uid:10001 我用ff浏览器测试,记录了一下sid和uid结果是 Sid:100 Uid:10000 [/quote] 这已经说明了,你认为是“第一次执行”时,实际上执行了2次。
Poopaye 2016-08-29
  • 打赏
  • 举报
回复
你要想解决就把问题说的详细点 1、Sid是什么,怎么获取的,怎么保存的 2、浏览器通过什么代码来访问服务器的 3、浏览器访问发送的是什么数据 4、……
啾啾我 2016-08-29
  • 打赏
  • 举报
回复
引用 2 楼 sp1234 的回复:
你认为的“第一次执行”是你的感觉,你有记录能看出实际收到了几次请求吗?
当然我 Sid = -1;后面我还做了读取xml文件,然后判断,等操作,但不至于影响这个异步!
啾啾我 2016-08-29
  • 打赏
  • 举报
回复
引用 2 楼 sp1234 的回复:
你认为的“第一次执行”是你的感觉,你有记录能看出实际收到了几次请求吗?
我用ie8浏览器,记录了一下sid和uid结果是 Sid:100 Uid:10000 Sid:-1 Uid:10001 我用ff浏览器测试,记录了一下sid和uid结果是 Sid:100 Uid:10000
  • 打赏
  • 举报
回复
你认为的“第一次执行”是你的感觉,你有记录能看出实际收到了几次请求吗?
啾啾我 2016-08-29
  • 打赏
  • 举报
回复
这个应该跟浏览器没有什么关系,我这代码也没有发现什么不对的地方啊,各位大神看看代码有问题吗?

62,025

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧