C # проблема с передачей токенов в чате клиент-сервер - PullRequest
0 голосов
/ 21 мая 2011

У меня проблема с передачей токенов в клиент-серверном приложении C #.Не могли бы вы помочь мне с этим, пожалуйста?Во-первых, я описываю ситуацию, во-вторых, я вставляю некоторый исходный код, в-третьих, я дам ссылку на решения Visual Studio.

Итак, ситуация такова: я создал многопоточный tcp-чат клиент-сервер.Все работает нормально, все пользователи могут писать сообщения одновременно, и все пользователи видят все.

Проблема в том, что мне нужно, чтобы сервер передавал токен одному пользователю за раз, поэтому только один пользователь может отправлять сообщения одновременно, когда все остальные пользователи будут только слушать.Токен должен передаваться пользователям в порядке присоединения к серверу в течение 10 секунд.

Пример: пользователь A присоединился к серверу, пользователь B присоединился к серверу, пользователь C присоединился к серверу.Сервер передает токен пользователю A в течение 10 секунд, а пользователь A может писать сообщения в течение 10 секунд (например, кнопка отправки отключена по умолчанию, и сервер передает token = true клиенту. Если токен имеет значение true, кнопка отправки активна в течение 10секунд, а затем токен снова становится ложным).Через 10 секунд сервер передает токен пользователю B, а пользователь B может писать сообщения в течение 10 секунд и т. Д. Как это сделать?

Вот исходный код сервера:

namespace Serverchat
{
class Serwer
{
    public static Hashtable klienci = new Hashtable();

    static void Main(string[] args)
    {
        IPAddress IP = IPAddress.Parse("127.0.0.1");
        int port = 8888;

        TcpListener serwer = new TcpListener(IP, port);
        TcpClient gniazdo = default(TcpClient);

        serwer.Start();
        Console.WriteLine("Token passing simulation\r\nAddress: "+IP+":"+port+"\r\n");

        while (true)
        {
            gniazdo = serwer.AcceptTcpClient();
            byte[] odczyt = new byte[10024];
            string odczytsub = "";

            gniazdo.GetStream().Read(odczyt, 0, gniazdo.ReceiveBufferSize);
            odczytsub = (Encoding.ASCII.GetString(odczyt)).Substring(0, (Encoding.ASCII.GetString(odczyt)).IndexOf("~"));
            klienci.Add(odczytsub, gniazdo);
            rozglos("", odczytsub);
            Console.WriteLine(odczytsub + " joined server.");
            obslugaKlienta klient = new obslugaKlienta();
            klient.startObslugiKlienta(gniazdo, odczytsub);
        }
    }

    public static void rozglos(string wiadomosc, string nazwaUzytkownika)
    {
        foreach (DictionaryEntry klient in klienci)
        {
            TcpClient gniazdo = (TcpClient)klient.Value;
            Byte[] zapis = null;

            if (wiadomosc != "")
            {
                zapis = Encoding.ASCII.GetBytes(nazwaUzytkownika + ":" + wiadomosc + "`");
            }
            else
            {
                zapis = Encoding.ASCII.GetBytes(nazwaUzytkownika + " joined server:");
            }
            gniazdo.GetStream().Write(zapis, 0, zapis.Length);
            gniazdo.GetStream().Flush();
        }
    }
}

public class obslugaKlienta
{
    TcpClient gniazdo;
    string klient;

    public void startObslugiKlienta(TcpClient gniazdo, string klient)
    {
        this.gniazdo = gniazdo;
        this.klient = klient;
        Thread klientWatek = new Thread(komunikacja);
        klientWatek.Start();
    }

    private void komunikacja()
    {
        byte[] odczyt = new byte[10024];
        string odczytsub = "";

        while (true)
        {
            gniazdo.GetStream().Read(odczyt, 0, gniazdo.ReceiveBufferSize);
            odczytsub = Encoding.ASCII.GetString(odczyt).Substring(0, Encoding.ASCII.GetString(odczyt).IndexOf("~"));
            Console.WriteLine(klient + ": " + odczytsub);
            Serwer.rozglos(Convert.ToString(odczytsub), klient);
        }
    }
}
}

Для записи rozglos - это функция, которая передает сообщения всем.

Вот исходный кодклиент:

namespace TRKlient
{
public partial class Klient : Form
{
    TcpClient gniazdo = new TcpClient();
    byte[] zapis;
    string dane = null;

    private void buttonWyslij_Click(object sender, EventArgs e) // Sending message
    {
        zapis = Encoding.ASCII.GetBytes(tbWiadomosc.Text + "~");
        gniazdo.GetStream().Write(zapis, 0, zapis.Length);
        gniazdo.GetStream().Flush();
    }

    private void buttonPolacz_Click(object sender, EventArgs e) // Connecting with server
    {
        dane = "Connected with Token Ring.";
        wyswietlWiadomosc();
        gniazdo.Connect(tbIP.Text, 8888);
        zapis = Encoding.ASCII.GetBytes(tbUser.Text + "~");
        gniazdo.GetStream().Write(zapis, 0, zapis.Length);
        gniazdo.GetStream().Flush();
        Thread klientWatek = new Thread(odbierzWiadomosc);
        klientWatek.Start();
        buttonPolacz.Enabled = false;
    }

    private void odbierzWiadomosc() // Reading data from stream
    {
        while (true)
        {
            byte[] odczyt = new byte[10024];
            gniazdo.GetStream().Read(odczyt, 0, gniazdo.ReceiveBufferSize);
            dane = Encoding.ASCII.GetString(odczyt);
            wyswietlWiadomosc();
        }
    }

    private void wyswietlWiadomosc() // Shows received messages in chat textbox
    {
        if (this.InvokeRequired)
            this.Invoke(new MethodInvoker(wyswietlWiadomosc));
        else
        tbChat.Text += "\r\n # " + dane;
    }

    public Klient() 
    {
        InitializeComponent();
    }
}
}

Вот ссылка на оба решения в Visual Studio 2010: http://www.speedyshare.com/files/28562696/client-server.rar

Пожалуйста, помогите мне, ребята, это очень важно для меня, и я исчерпалидей.

Вы много раз мне помогали, так что спасибо заранее, Питер.

РЕДАКТИРОВАТЬ: Отправка сообщения клиентом с токеном может быть так же просто, как автоматическая отправка первого письма его псевдонима.Все может быть максимально просто, мне нужна только рабочая передача токенов.Спасибо за ваши ответы.

1 Ответ

0 голосов
/ 21 мая 2011

Давайте посмотрим на различия между старыми и новыми требованиями:

ранее вы хотели отправлять сообщения от клиента на сервер и оттуда всем (другим) клиентам, что прекрасно работает, если вы передаете сообщение в виде строки, без какого-либо другого протокола ... если клиент что-то получает, Вы можете быть уверены, что это строка сообщения, которая должна отображаться в текстовом поле чата ...

теперь все немного по-другому: вы должны различать сообщения, которые должны отображаться, и сообщения управления, которые информируют о токене ... вам нужен какой-то протокол для этого ...

что-то, что сообщает слушателю, содержит ли сообщение сообщение чата или управляющее сообщение.

управляющие сообщения информируют клиента о таких вещах, как «эй, клиент ... вы получили токен ... отправка разрешена на 10 секунд ...», или «ваше разрешение на отправку было отменено» и т. Д.

на основе этих сообщений вы можете включить / отключить кнопку отправки вашего клиента ...

с другой стороны, вам также потребуется реализовать серверную часть: управление токеном и отправка соответствующих управляющих сообщений клиентам.

...