使用C#中的异步套接字在任何给定时间将消息发送回客户端列??表
我已经设置了异步服务器,它通过连接,接收和发回消息到连接客户端完美地工作.
服务器本身是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 { } } 我希望它会有所帮助:) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |