使用C#中的异步套接字在任何给定时间将消息发送回客户端列​​表

使用C#中的异步套接字在任何给定时间将消息发送回客户端列​​表,第1张

概述我已经设置了异步服务器,它通过连接,接收和发回消息到连接客户端完美地工作. 服务器本身是Game-World-Server(mmorpg风格).当用户将其位置发送到其所在的位置时,我需要使用PlayerPositionNotice将其推送到所有客户端.我知道我在这里缺少一些基本的东西,但是当我尝试保存在accept方法中创建的StateObject时,并使用该套接字在任何给定时间将信息发送回播放器 我已经设置了异步服务器,它通过连接,接收和发回消息到连接客户端完美地工作.

服务器本身是Game-World-Server(mmorpg风格).当用户将其位置发送到其所在的位置时,我需要使用PlayerpositionNotice将其推送到所有客户端.我知道我在这里缺少一些基本的东西,但是当我尝试保存在accept方法中创建的StateObject时,并使用该套接字在任何给定时间将信息发送回播放器,因为套接字已关闭而失败. = /不知道为什么会发生这种情况,我会在这个问题上搜索几个引擎但是又回来了.

这就是我创建服务器的方式:

首先,我们有全球性的东西:

public StateManager _stateManager = new StateManager();    public bool IsClosing = false;    private const int _port = 1025;    private IPHostEntry _localhost;    private IPEndPoint _endpoint;    private Socket _serverSocket;    private Thread _serverThread;

第二个我们有初始化的东西:

public voID Start()    {        _serverThread = new Thread(Initialize);        _serverThread.Start();    }    /// <summary>    /// Main entry point for the server    /// </summary>    private voID Initialize()    {        Console.Writeline("Server Main Socket Thread Initialized.");        _localhost = Dns.GetHostEntry(Dns.GetHostname());        try        {            _endpoint = new IPEndPoint(_localhost.AddressList[0],_port);            _serverSocket = new Socket(_endpoint.Address.AddressFamily,SocketType.Stream,ProtocolType.Tcp);            _serverSocket.Bind(_endpoint);            _serverSocket.Listen(100);            _serverSocket.BeginAccept(new AsyncCallback(acceptCallback),_serverSocket);        }        catch (ArgumentOutOfRangeException)        {            Console.Writeline(" >> Port number " + _port + " would seem to be invalID,should be between 1024 and 65000");        }        catch (SocketException)        {            Console.Writeline(" >> Could not create socket,check to make sure not duplicating port");        }        catch (Exception e)        {            Console.Writeline(" >> Error occured while binding socket,IE:" + e.InnerException);        }    }

到目前为止这么好,我希望..现在到服务器类的其余部分.

private voID acceptCallback(IAsyncResult result)    {        Console.Writeline("Connection Accepted");        StateObject state = null;        try        {            state = new StateObject            {                workSocket = ((Socket)result.AsyncState).EndAccept(result)            };            _stateManager.AddConnection(state);            state.workSocket.BeginReceive(state.buffer,state.buffer.Length,SocketFlags.None,new AsyncCallback(receiveCallback),state);            _serverSocket.BeginAccept(new AsyncCallback(acceptCallback),_serverSocket);        }        catch (SocketException)        {            _stateManager.RemoveConnection(state);            _serverSocket.BeginAccept(new AsyncCallback(acceptCallback),_serverSocket);        }        catch (Exception)        {            _stateManager.RemoveConnection(state);            _serverSocket.BeginAccept(new AsyncCallback(acceptCallback),_serverSocket);        }    }    private voID receiveCallback(IAsyncResult result)    {        var state = (StateObject)result.AsyncState;        try        {            // Buffer and count bytes read            int bytesRead = state.workSocket.EndReceive(result);            if (!state.workSocket.Connected)                _stateManager.RemoveConnection(state);            if (bytesRead > 0)            {                // Parse the message to the protocol manager and return a reply                var replyingData = ProtocolManager.Parse(state.buffer);                if (replyingData != null)                    Send(replyingData,state);                //Queue the next receive                state.workSocket.BeginReceive(state.buffer,state);            }            else            {                _stateManager.RemoveConnection(state);            }        }        catch (SocketException e)        {            _stateManager.RemoveConnection(state);        }    }    public bool Send(byte[] message,StateObject state)    {        Console.Writeline("Sending " + message.Length + " bytes");        if (state != null && state.workSocket.Connected)        {            lock (state.workSocket)            {                //we use a blocking mode send,no async on the outgoing                //since this is primarily a multithreaded application,shouldn't cause problems to send in blocking mode                state.workSocket.Send(message,message.Length,SocketFlags.None);            }        }        else return false;        return true;    }

stateManager包含一个StateObject列表.下面你可以看到我是如何构建它们的.

国家经理:

public class StateManager{    private List<StateObject> _connections = new List<StateObject>();    public voID AddConnection(StateObject so)    {        lock (_connections)        {            _connections.Add(so);        }    }    public voID RemoveConnection(StateObject so)    {        if (so.workSocket != null)        {            so.workSocket.Close();            lock (_connections)            {                _connections.Remove(so);            }        }    }}

国家对象

public class StateObject{    public Socket workSocket = null;    public const int BufferSize = 1024;    public byte[] buffer = new byte[BufferSize];    public StringBuilder sb = new StringBuilder();}

我的问题在于,无论何时此列表​​中的任何人发送了我想要向其他客户发回通知的内容.我如何以及在何处实现此目的?谁能踢我正确的方向? =)

解决方法 这段代码似乎是正确的,我不知道为什么你得到“socket is closed”错误,但是还有另一个问题:在Send(byte [] message,StateObject state)方法中,因为你在从用户接收时调用了这个将收到的数据发回给该用户(不是所有其他用户都注意到它们)

如您所说,如果您需要向所有其他用户发送新位置:

收到新位置时,调用此方法而不是Send(byte []消息,StateObject状态).

public voID NoticeAllusers(byte []buffer,StateObject state)    {        foreach(StateObject obj in _stateManager._connections)        {            if (obj != state)            {                obj.workSocket.BeginSend(buffer,<parameters you>....,new AsyncCallback(OnSend) state.workSocket);            }        }    }    public voID OnSend(IAsyncResult ar)    {        try        {            Socket sock = (Socket)ar.AsyncState;            sock.EndSend(ar);        }        catch { }    }

我希望它会有所帮助:)

总结

以上是内存溢出为你收集整理的使用C#中的异步套接字在任何给定时间将消息发送回客户端列​​表全部内容,希望文章能够帮你解决使用C#中的异步套接字在任何给定时间将消息发送回客户端列​​表所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/1234284.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-06
下一篇 2022-06-06

发表评论

登录后才能评论

评论列表(0条)

保存