2014-10-05 77 views
0

對不起,一遍又一遍詢問'相同'的事情。這是另一個聊天版本。隨着大量搜索,我終於找到了如何通過客戶端列表(或至少我希望如此)到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(); 
      } 
    } 
} 
+4

是否需要使用TcpClient?你是在做這個練習嗎?爲什麼不看像SignalR這樣的框架呢? – zaitsman 2014-10-05 01:16:49

+0

一旦創建了一套TCP/IP方法集,但它在6 - 7年前,記不起多少。但我確實記得,與TcpClient相比,我發現使用Socket直接工作更容易。你問「不知道它們是否可以同時讀/寫」 - 是的,通過適當的多線程,你可以同時運行許多Socket連接,同時讀取和/或寫入。互聯網上有很多關於此的資源,只需搜索「C#chat tcp/ip」即可。 – RenniePet 2014-10-05 01:27:38

+0

是的,它必須使用TcpClient來完成。我以爲我已經解決了大部分問題。不知道服務器沒有正確寫入客戶端的內容。 (或者,如果客戶多線程實際上正常工作) – GytisK 2014-10-05 09:44:59

回答

1

TCP是不是設計了廣播這就是爲什麼你通過所有的客戶端不必循環。更好的方法是使用支持brodcast的協議使用SignalR Framework,或者如果您希望baremetal訪問使用UDP。這是一個很棒的SignalR聊天示例。

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

+0

是不是SignalR僅適用於使用Web瀏覽器技術的客戶端? (對於OP可能會也可能不會)。我懷疑UDP是否可行,除非所有聊天客戶端與聊天服務器位於同一網段。你當然不會通過防火牆或通過互聯網獲取UDP。 – RenniePet 2014-10-05 02:18:29

+0

我不能使用框架。它必須儘可能接近我迄今爲止所做的。任何想法有什麼不對?服務器寫入客戶端不工作,還是客戶端線程讀取/寫入? – GytisK 2014-10-05 09:46:35

相關問題