Дублирование TcpClient в C# - PullRequest
0 голосов
/ 03 мая 2020

Я делаю несколько чатов на одном сервере с клиентами. поэтому мне нужно управлять клиентами с помощью многопоточности.

позвольте мне просто описать мой код,

m_listner = new TcpListner(localAddr, PORT);
m_listner.Start();
m_bStop = true;
while(m_bStop)
{
    TcpClient hClient = new TcpClient();
    hClient = m_listner.AcceptTcpClient();
    Thread t = new Thread(()=>client_handler(hClient);
    t.IsBackground = true;
    t.Start();
}

, а затем в client_handler, инициализировать сетевой поток и поместить клиента в словарь для управления ими.

Моя цель - сохранить клиентов и использовать их, когда сервер отправляет сообщение всем клиентам. Но клиенты обрабатываются как один и тот же клиент, потому что TcpClient не обновляются и просто одинаковы. Кажется, что AcceptTcpClient() возвращает тот же объект. Могу я узнать, где проблема?

Ответы [ 3 ]

0 голосов
/ 04 мая 2020

Я обнаружил, что это вызвано другой проблемой. Спасибо за ответ

0 голосов
/ 08 мая 2020

Если я правильно прочитал, вы хотите способ обработки / хранения нескольких клиентов? Если это так, то вот что я сделал в моем проекте (в основном сервер с большим количеством клиентов)

внутри сервера я запускаю поток, делающий это:

private static void WaitForConnection()
    {
        try
        {
            TcpClient client = listener.AcceptTcpClient();
            Log("Client Connected!");

            Thread clienThread = new Thread(delegate () { ClientThread(client); });
            clienThread.IsBackground = true;
            clienThread.Start();
            WaitForConnection();
        }
        catch (Exception e)
        {
            Log(string.Format("ERROR at WaitForConnection: {0}", e.Message));
            WaitForConnection();
        }
    }

ClientThread:

public static void ClientThread(TcpClient client)
    {
        int clientID = nextTCPClientID;
        nextTCPClientID++;
        dicTCPclients.Add(clientID, client);
        dicNetworkstreams.Add(ns, clientID);
        dicClientIDToNetworkstreams.Add(clientID, ns);
        // do more stuff here ...
    }

На моем сервере есть несколько словарей, в которых хранится целое число, представляющее clientID и TCPClient / NetworkStream.

Если вы хотите отправить что-то всем клиентам, вы можете использовать что-то вроде этого

foreach (NetworkStream ns in dicNetworkstreams.Keys)
{
        //Send here
        byte[] lengthBuffer = BitConverter.GetBytes(data.Length);
        ns.Write(lengthBuffer, 0, lengthBuffer.Length);
        ns.Write(data, 0, data.Length);
}

Также, прочитав ваш вопрос еще раз, попробуйте вызвать метод для вашего AcceptTcpClient(), аналогично тому, что я использовал (WaitForConnection()). Это может решить проблему с дубликатами.

0 голосов
/ 03 мая 2020

Вам необходимо запустить поток, прежде чем запускать клиент

...