【问题标题】:How to send messages to all clients in multithread chat server?如何向多线程聊天服务器中的所有客户端发送消息?
【发布时间】:2014-11-29 16:11:53
【问题描述】:

很抱歉一遍又一遍地询问“相同”的事情。这是聊天的另一个版本。经过大量搜索,我终于找到了如何将客户列表(或至少我希望如此)传递给 Chat 函数。

但是我不知道这是否应该工作:

每次客户端连接时:

clients.Add(clientSocket);

var ctThread = new System.Threading.Thread(() => Chat(clients));

Chat 函数希望通过

正确接收客户端

public void Chat(List<TcpClient> clients)

然后写出来

 foreach (var client in clients)
    {
        writer.Write(message);
    } 

客户端有 2 个线程(不确定它们是否可以同时读/写)

    Thread ctThread = new Thread(Write);
    Thread ctThread2 = new Thread(Read);
    ctThread2.Start();
    ctThread.Start();

我是否正确地将客户列表传递给函数?它实际上可以正确发送消息吗?因为现在服务器没有响应我在客户端输入的任何内容。

完整代码:

服务器

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Net.Sockets;
using System.IO;

namespace MultiServeris
{
    class Multiserveris
    {
        static void Main(string[] args)
        {
            TcpListener ServerSocket = new TcpListener(1000);         
            ServerSocket.Start();                                     
            List<TcpClient> clients = new List<TcpClient>();
            Console.WriteLine("Server started.");
            while (true)
            {
                TcpClient clientSocket = ServerSocket.AcceptTcpClient();
                handleClient client = new handleClient();
                clients.Add(clientSocket);
                client.startClient(clientSocket,clients);
            }
        }
    }

    public class handleClient
    {
        TcpClient clientSocket;                                 
        public void startClient(TcpClient inClientSocket, List<TcpClient> clients)
        {
            this.clientSocket = inClientSocket;
            var ctThread = new System.Threading.Thread(() => Chat(clients)); 
        }

        public void Chat(List<TcpClient> clients)
        {
            BinaryReader reader = new BinaryReader(clientSocket.GetStream());
            BinaryWriter writer = new BinaryWriter(clientSocket.GetStream());
            while (true)
            {
                string message = reader.ReadString();
                foreach (var client in clients)
                {
                    writer.Write(message);
                } 
            }
        }
    }
}

客户

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.IO;
using System.Threading;


namespace Klientas
{
    class Klientas
    {
        public static void Write()
        {
            while (true)
            {
                TcpClient clientSocket = new TcpClient("localhost", 1000);
                string str = Console.ReadLine();
                BinaryWriter writer = new BinaryWriter(clientSocket.GetStream());
                writer.Write(str);
            }
        }
        public static void Read()
        {
            while (true)
            {
                TcpClient clientSocket = new TcpClient("localhost", 1000);
                BinaryReader reader = new BinaryReader(clientSocket.GetStream());
                string message = reader.ReadString();
                Console.WriteLine(message);
            }
        }

        static void Main(string[] args){
            Thread ctThread = new Thread(Write);
            Thread ctThread2 = new Thread(Read);
            ctThread2.Start();
            ctThread.Start();
           }
    }
}

【问题讨论】:

  • 是否需要使用TcpClient?你这样做是为了锻炼吗?为什么不看看 SignalR 这样的框架?
  • 曾经创建过一套TCP/IP的方法,不过是6-7年前的事了,记不太清了。但我确实记得,我发现直接使用 Socket 比使用 TcpClient 更容易。你问“不确定他们是否可以同时读/写”——是的,通过适当的多线程,你可以同时运行很多很多 Socket 连接,同时读和/或写。网上有很多关于这个的资源,直接搜索“C# chat tcp/ip”即可。
  • 是的,必须使用 TcpClient 来完成。我以为我已经解决了大部分问题。不知道服务器正确写入客户端缺少什么。 (或者如果客户端多线程实际上像现在一样工作)

标签: c# multithreading list sockets chat


【解决方案1】:

TCP 不是为广播而设计的,这就是为什么您必须遍历所有客户端的原因。更好的方法是使用支持广播的协议,使用 SignalR 框架,或者如果您希望裸机访问使用 UDP。这是一个很棒的 SignalR 聊天示例。

https://dhavalupadhyaya.wordpress.com/tag/signalr-chat-example/

【讨论】:

  • SignalR 不是仅适用于使用 Web 浏览器技术的客户端吗? (这对于 OP 来说可能合适,也可能不合适。)而且我怀疑 UDP 是否可行,除非所有聊天客户端都与聊天服务器位于同一网段。您当然不会通过防火墙或 Internet 获取 UDP。
  • 我不能使用框架。它必须尽可能接近我目前所拥有的。有什么想法有什么问题吗?是服务器写入客户端不工作,还是客户端线程读取/写入?
猜你喜欢
  • 2016-07-23
  • 1970-01-01
  • 2023-04-05
  • 2020-01-06
  • 1970-01-01
  • 1970-01-01
  • 2019-02-26
  • 2015-02-17
  • 2013-04-09
相关资源
最近更新 更多