Почему мой сервер сокетов C # не позволяет нескольким экземплярам клиента подключаться только с локального компьютера? - PullRequest
0 голосов
/ 17 февраля 2019

У меня ранее работал этот код, и я не уверен в причине проблемы, с которой я сейчас сталкиваюсь.Я пишу простое клиент-серверное приложение для зашифрованного чата.Сервер допускает несколько одновременных клиентов.Когда я связываю сервер с локальным IP-адресом, я могу одновременно подключаться к нескольким локальным клиентам, но когда я связываю его с внешним IP-адресом, будет подключаться только первый экземпляр на локальном компьютере, но другие устройства могут соединяться с несколькими экземплярами одновременно,В этом случае даже закрытие первого экземпляра не позволит другому подключиться, и AcceptCallBack никогда не вызывается.Я не смог найти никаких других сообщений об этой проблеме.Причины, которые приходят на ум, включают то, что я допустил какую-то ошибку в коде, или мне нужно отдельно прослушивать локальные соединения и удаленные соединения, или что это проблема маршрутизатора / брандмауэра.

Для моего сервера яесть:

public partial class frmServer : Form
{   

    Thread listenThread;
    private static bool listening = false;
    private static List<StateObject> Users = new List<StateObject>();

    public frmServer()
        {
            InitializeComponent();
        }

    private void frmServer_Load(object sender, EventArgs e)
            {
                listenThread = new Thread(new ThreadStart(StartListening));
                listenThread.Start();
            }
            public static void StartListening()
            {
                IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, 19541);

                // Create a TCP/IP socket.  
                Socket listener = new Socket(AddressFamily.InterNetwork,
                    SocketType.Stream, ProtocolType.Tcp);

                // Bind the socket to the local endpoint and listen for incoming connections.  
                try
                {

                    listener.Bind(localEndPoint);               
                    listener.Listen(100);
                    listener.BeginAccept(
                           new AsyncCallback(AcceptCallback),
                           listener);
                    listening = true;
                    while (true)
                    {                           
                        //check if there are new connections
                        if (!listening)
                        {
                            listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
                            listening = true;
                        }

                        Thread.Sleep(50);
                    }

                }
                catch (Exception e)
                {
                    Console.WriteLine(e.ToString());
                }
            }
             public static void AcceptCallback(IAsyncResult ar)
        {
            // Get the socket that handles the client request.  
            Socket listener = (Socket)ar.AsyncState;
            Socket handler = listener.EndAccept(ar);            
            listening = false;
            // Create the state object.  
            StateObject state = new StateObject();
            state.workSocket = handler;
            Users.Add(state);            
        }
}
 public class StateObject
{
    // Client  socket.  
    public Socket workSocket = null;
    // Size of receive buffer.  
    public const int BufferSize = 1024;
    // Receive buffer.  
    public byte[] buffer = new byte[BufferSize];
    // Received data string.  
    public StringBuilder sb = new StringBuilder();
    //user info
}

И для клиента у меня есть

public partial class frmClient : Form
{        

    public frmClient()
        {
            InitializeComponent();
        }  

    private void frmClient_Load(object sender, EventArgs e)
    {
        StartClient();            
    }

    private void StartClient()
    {
        // Connect to a remote device.  
        try
        {
            // Establish the remote endpoint for the socket.   
             IPHostEntry ipHostInfo = Dns.GetHostEntry("Remote Host Address");                
            IPAddress ipAddress = ipHostInfo.AddressList[0];
            IPEndPoint remoteEP = new IPEndPoint(ipAddress, port);

            // Create a TCP/IP V4 socket.  
            Socket client = new Socket(ipAddress.AddressFamily,
                SocketType.Stream, ProtocolType.Tcp);

            // Connect to the remote endpoint.  
            client.BeginConnect(remoteEP,
                new AsyncCallback(ConnectCallback), client);    

        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
        }
    }
    private void ConnectCallback(IAsyncResult ar)
    {
        try
        {
            // Retrieve the socket from the state object.  
            Socket client = (Socket)ar.AsyncState;

            // Complete the connection.  
            client.EndConnect(ar);

            // Signal that the connection has been made. 
            Console.WriteLine("Socket connected to {0}",
                client.RemoteEndPoint.ToString());                 

        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
        }
    }
...