使用 C# 进行客户端-服务器聊天以流式传输在线用户列表

发布于 2024-12-17 06:36:02 字数 1103 浏览 2 评论 0原文

对于学校作业,我们必须用 C# 制作一个客户端服务器聊天程序。我以前从未做过任何网络工作,所以这对我来说非常困惑。我读了一本关于 C# 网络的书,并且能够使用二进制读取器和写入器以及 TCP 套接字进行非常基本的聊天。但是,对于分配,我必须让客户端列出所有连接的用户。现在,我如何才能使客户端仅在有人在服务器上断开连接或连接时读取列表流。我可以让客户端始终下载新列表,但我觉得发送了很多冗余数据。

顺便说一句,我对客户端/服务器如何知道流中的数据是什么感到困惑。到目前为止,我只有一个通过流发送的表示消息的字符串。有没有办法将某种签名或其他内容附加到正在发送的数据中,以便服务器或客户端知道该特定数据是用户名或可能是要显示的消息。

编辑: 我的流有问题。我有一个在自己的线程中运行的方法,该方法始终检查发送的信息。它列出了一个字符串(用于显示消息的消息)和一个包含已连接用户的列表。问题在于发送数据的顺序并不总是一致的。有时消息是第一个,其他消息是列表,有时它只是流中的一条消息。有没有办法知道正在读取哪些数据?这是我的客户端监听器。

private void incoming()
    {
        while (true)
        {
            try
            {
                string read = reader.ReadString();
                if (read.Length > 0)
                    lbOutput.Items.Add(read);
                    lbUsers.Items.Clear();

                List<string> users = (List<string>)binaryFormatter.Deserialize(stream);
                foreach (string user in users)
                    lbUsers.Items.Add(user.ToString());
            }
            catch { lbOutput.Items.Add("Error reading the stream"); }
        }

For a school assignment we have to make a client server chat program in C#. I have never done any networking in the past before so its very confusing for me. I read a book on C# networking, and I was able to make a very basic chat that works using binary readers and writers and a TCP socket. However for the assignment I have to make the client list all connected users. Now, how would I make it so that the client only reads the stream for a list when someone disconnects or connects on the server. I could make it so that the clients is always downloading a new list, but I feel that's a lot of redundant data being sent.

On a side note, I'm confused with how the client/server knows what the data in the stream is. So far I only have a string being sent through the stream which represents a message. Is there a way to attach some sort of signature or something to the data being sent so that the server or client knows that that specific data is the username or perhaps a message to be displayed.

Edit:
I'm having issues with the stream. I have a method that's running in its own thread that's always checking for information being sent. Its listing for both a string that's a message to display message and a List containing users connected. The problem is that the order of the data being sent isn't always in a consistent order. Sometimes the message is first, others the list is, and sometimes its only a message in the stream. Is there a way to tell what data is being read? Here is my client side listener.

private void incoming()
    {
        while (true)
        {
            try
            {
                string read = reader.ReadString();
                if (read.Length > 0)
                    lbOutput.Items.Add(read);
                    lbUsers.Items.Clear();

                List<string> users = (List<string>)binaryFormatter.Deserialize(stream);
                foreach (string user in users)
                    lbUsers.Items.Add(user.ToString());
            }
            catch { lbOutput.Items.Add("Error reading the stream"); }
        }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

倾听心声的旋律 2024-12-24 06:36:02

当新客户端连接时,它应该向服务器发送一条消息,通知它已连接并要求它存储其名称。然后,服务器可以使用新列表(或仅新客户端的名称)向所有其他客户端广播消息。粗略概述:

public class Server {

     public void StartAcceptingConnections() {

          while(true) {
              // accept socket connection
              // read new user name
              foreach(Client cl in connectedClients) {
                  // send new user name to cl.Socket
              }    
          }             
     }
}

同时,您正在从要路由的客户端接收消息(我假设)。当客户端离开时,它将再次发送断开连接消息,并且服务器可以将更改广播给其余客户端。

如果您想要处理的不仅仅是字节和字符串,您可以尝试通过序列化发送整个对象。看一下本教程:http://msdn.microsoft.com/en-我们/杂志/cc301761.aspx

When a new client connects, it should send a message to the server to inform it that it has connected and ask it to store its name. Then the server can broadcast a message to all other clients with the new list (or just the name of the new client). Rough outline:

public class Server {

     public void StartAcceptingConnections() {

          while(true) {
              // accept socket connection
              // read new user name
              foreach(Client cl in connectedClients) {
                  // send new user name to cl.Socket
              }    
          }             
     }
}

In parallel, you are receiving messages from clients to be routed (I assume). When a client leaves, it will again send a disconnect message and the server can broadcast the change to the rest of the clients.

If you want to work with more than just bytes and strings, you can try to send entire object by serialization. Have a look at this tutorial: http://msdn.microsoft.com/en-us/magazine/cc301761.aspx.

冷默言语 2024-12-24 06:36:02

既然您说它需要是一个客户端/服务器应用程序,我将使用带有双工绑定的 WCF 来解决这个问题。这允许服务将消息发送回客户端,而不仅仅是接收它们(有点像事件)。

可以在此处找到说明:

http://msdn.microsoft.com/en- us/library/ms731064.aspx

如果解决方案不必是客户端/服务器,则更优雅的解决方案可能是使用点对点方法,其中没有服务器并且所有客户端在一种网络。网络上有一些示例显示了如何准确地实现您实际上想要的内容(并不是我鼓励您作弊......)。例如

http://www.codeproject.com/KB/WCF/Chat_application_using_WC.aspx

Since you said it needs to be a client/server application, I would approach this using WCF with a duplex binding. This allows the service to send messages back to the client rather than just receive them (kind of like eventing).

An explanation can be found here:

http://msdn.microsoft.com/en-us/library/ms731064.aspx

If the solution did not have to be client/server, a more elegant solution could be to use a peer-to-peer approach where there is no server and all the clients communicate together in a kind of web. There are sample on the web showing how to exactly what you want in fact (not that I'm encouraging you to cheat...). For example

http://www.codeproject.com/KB/WCF/Chat_application_using_WC.aspx

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文