客户端-服务器聊天中令牌传递同步的C#问题
我在C#客户机-服务器应用程序中传递令牌时遇到问题。你能帮我一下吗?首先我描述了情况,其次我粘贴了一些源代码,第三我将提供一个指向VisualStudio解决方案的链接 所以情况是这样的:我创建了多线程客户机-服务器tcp聊天。一切正常,所有用户都可以一次编写消息,所有用户都可以看到一切 问题是,我需要服务器一次将令牌传递给一个用户,这样一次只有一个用户可以发送消息,而所有其他用户都只能监听。令牌应按加入服务器的顺序传递给用户10秒 例如: 用户A加入服务器,用户B加入服务器,用户C加入服务器。服务器将令牌传递给用户A 10秒,用户A可以写入消息10秒(例如,发送按钮默认为禁用,服务器将令牌传递给客户端为true。如果令牌为true,发送按钮将启用10秒,然后令牌再次为false)。10秒后,服务器将令牌传递给用户B,用户B可以写消息10秒,以此类推。。如何做到这一点 以下是服务器的源代码:客户端-服务器聊天中令牌传递同步的C#问题,c#,synchronization,network-programming,client-server,token,C#,Synchronization,Network Programming,Client Server,Token,我在C#客户机-服务器应用程序中传递令牌时遇到问题。你能帮我一下吗?首先我描述了情况,其次我粘贴了一些源代码,第三我将提供一个指向VisualStudio解决方案的链接 所以情况是这样的:我创建了多线程客户机-服务器tcp聊天。一切正常,所有用户都可以一次编写消息,所有用户都可以看到一切 问题是,我需要服务器一次将令牌传递给一个用户,这样一次只有一个用户可以发送消息,而所有其他用户都只能监听。令牌应按加入服务器的顺序传递给用户10秒 例如: 用户A加入服务器,用户B加入服务器,用户C加入服务器。
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中两种解决方案的链接:
伙计们,请帮帮我,这对我很重要,我已经没有主意了
你帮了我很多次,所以提前谢谢你,彼得
编辑:客户端使用令牌发送消息可以简单到自动发送其昵称的第一个字母。一切尽可能简单,我只需要工作令牌传递。感谢您的回复。让我们看看新旧需求之间的差异: 以前,您希望将消息从客户机发送到服务器,然后从服务器发送到所有(其他)客户机,如果您将消息作为字符串传递,而不使用任何其他协议,则可以正常工作。。。如果客户端收到某个消息,您可以确定该消息字符串应该显示在您的聊天文本框中 现在情况有点不同了:您必须区分要显示的消息和通知令牌的控制消息。。。你需要的是某种协议 告诉侦听器消息是否包含聊天消息或控制消息的内容 控制消息通知客户端“嘿,客户端……您得到了令牌……允许发送10秒……”或“您的发送权限已被撤销”等信息 根据这些消息,您可以启用/禁用客户端的发送按钮
另一方面,您还必须实现服务器部分:管理令牌并向客户端发送适当的控制消息。谢谢您的回答,我明白您的意思。不幸的是,我仍然不知道如何在实践中做到这一点:(首先,您必须为这些消息定义一个协议。您可以定义自己的协议,或实现类似IRC协议()的内容,但IRC对于您的应用程序来说似乎有点过大。也许只需在每条聊天消息前面加上MSG,就可以使用令牌的控制消息“令牌”。只需查看第一个单词,即可将聊天信息与令牌区分开来,然后将字符串赋予相应的处理功能(聊天信息?->输出到用户/控制信息?->执行其他操作)