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

C# 在任何给定时间使用C中的异步套接字将消息发送回客户机列表#,c#,asynchronous,network-programming,asyncsocket,C#,Asynchronous,Network Programming,Asyncsocket,我已经设置了一个异步服务器,它通过连接、接收和向连接的客户机发回消息来完美地工作 服务器本身是一个游戏世界服务器(mmorpg风格)。当用户将其位置发送到其所在位置时,我需要使用PlayerPositionNotice将其发送给所有客户端。我知道这里缺少一些基本的东西,但当我试图保存在accept方法中创建的StateObject,并在任何给定时间使用该套接字将信息发送回播放机时,由于套接字已关闭,因此失败。=/不知道为什么会发生这种情况,我会在这上面搜索几个引擎,但结果是空的 以下是我创建服务

我已经设置了一个异步服务器,它通过连接、接收和向连接的客户机发回消息来完美地工作

服务器本身是一个游戏世界服务器(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);
        }
    }
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);
            }
        }
    }
}

我这里的问题是,每当这个列表中的任何人发送一些东西时,我都想向许多其他客户发回通知。如何以及在何处实施此功能?有人能把我踢向正确的方向吗?=)

这段代码似乎是正确的,我不知道为什么会出现“套接字已关闭”错误,但还有另一个问题:在Send(byte[]message,StateObject state)方法中,因为您在从用户接收数据时调用此函数,并将接收到的数据发送回该用户。(不要让所有其他用户注意到他们)

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

当接收到新位置时,调用此方法,而不是发送(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 { }
    }
public void NoticeAllusers(字节[]缓冲区,StateObject状态)
{
foreach(stateManager.\u连接中的StateObject对象)
{
如果(对象!=状态)
{
obj.workSocket.BeginSend(缓冲区,…,新异步回调(OnSend)状态。workSocket);
}
}
}
公共无效登录(IAsyncResult ar)
{
尝试
{
Socket sock=(Socket)ar.AsyncState;
短袜收尾(ar);
}
捕获{}
}

我希望这会有所帮助:)

谢谢阿拉布利。。这让我在前进的路上迈出了一步。。但是我的客户似乎忽略了我发送的任何东西(哦,套接字是关闭的,dissapeed=)…哎呀。。进入。。无论如何,首先我发送一条消息,然后我使用您的方法,忽略实际发送消息的客户端。但后来,其他客户甚至都没有对即将发生的事情保持警惕。我将进一步调查客户机部分(现在似乎是问题所在),看看我是否能解决这个问题!否则我会回到这里;)
public class StateObject
{
    public Socket workSocket = null;
    public const int BufferSize = 1024;
    public byte[] buffer = new byte[BufferSize];
    public StringBuilder sb = new StringBuilder();
}
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 { }
    }