[英]C# sockets with multiple clients (multiple threads approach)
TL;DR:我有一個 C# 服務器來管理一個客戶端。 讓它處理多個客戶端的最佳方法是什么?
完整解釋:
我正在實現一個需要同時處理多個客戶端的 C# 套接字服務器應用程序。
我的邏輯如下:
到目前為止,我的代碼只管理一個客戶端:
public partial class Form1 : Form
{
TcpListener listener;
Socket clientSock;
Thread listenThread, receiveThread;
string sendMsg, recvMsg;
byte[] sendMsgRaw, recvMsgRaw;
public Form1() {
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e) {
// Handler for onExit.
AppDomain.CurrentDomain.ProcessExit += new EventHandler(onExit);
}
private void listenButton_Click(object sender, EventArgs e) {
// Launch thread that listens for clients attempting to connect.
listener = new TcpListener(8888); // I know this method is deprecated, will fix.
listener.Start();
listenThread = new Thread(new ThreadStart(listenForClients));
listenThread.Start();
}
private void sendButton_Click(object sender, EventArgs e) {
// Send message to client.
sendMsg = sendTextbox.Text;
sendMsgRaw = Encoding.ASCII.GetBytes(sendMsg + "\r\n");
clientSock.Send(sendMsgRaw);
}
private void listenForClients() {
// Listen for connection attempts.
clientSock = listener.AcceptSocket();
disableButton(listenButton);
receiveThread = new Thread(new ThreadStart(readFromClient));
receiveThread.Start();
}
private void readFromClient() {
// Read response from client.
while(true) {
recvMsg = "";
recvMsgRaw = new byte[1024];
clientSock.Receive(recvMsgRaw);
recvMsg = Encoding.ASCII.GetString(recvMsgRaw);
appendRecvTextbox(recvMsg);
}
}
private void appendRecvTextbox(string message) {
// Append client's reply to a textbox.
if(InvokeRequired) {
this.Invoke(new Action<string>(appendRecvTextbox), new object[] { message });
return;
}
recvTextbox.AppendText(message + Environment.NewLine);
}
private void disableButton(Button btn) {
// Disable a button.
if(InvokeRequired) {
this.Invoke(new Action<Button>(disableButton), new object[] { btn });
return;
}
btn.Enabled = false;
}
private void onExit(object sender, EventArgs e) {
// Executed on program exit.
clientSock.Close();
}
}
這是我想到的表格截圖: http : //prntscr.com/azkaed
Basically when a listbox item (client) is selected, the received data area would change according to what has been received by that client.
And when that same listbox item (client) is selected and send a message, it would be sent to that client and that client alone (no multicast or something similar).
僅供參考,我將按照相同的原則實現文件傳輸。
我不是要你們謙虛的人為我編寫我的應用程序,那是徒勞的,我什么也學不到。 我想了解和處理所有這些是如何工作的。 顯然,可以幫助我理解的代碼示例非常非常受歡迎。 潛在的問題和疑問:
所以回到主要問題:在當前狀態下,應用程序處理一個客戶端。 我怎樣才能讓它處理多個客戶端? 請注意,我選擇多線程是因為我一次連接的客戶端數量有限 - 少於 10 個客戶端。
我知道這不是我要問的一個簡單問題 - 但每個答案都會受到深深的贊賞。
如果有任何區別,客戶端將使用 c/cpp、java、python 等語言的混合編寫,我什至考慮使用 PHP。 這是為了學習的唯一目的。 但我懷疑這很重要。 由於邏輯較少,客戶端似乎更容易編程,所以我不需要任何幫助。
預先感謝您的任何建議。
首先,有這個鏈接: http : //www.codeproject.com/Articles/429144/Simple-Instant-Messenger-with-SSL-Encryption-in-Cs
現在我將回答您的問題:
沒有像“太多線程”這樣的東西。 你可以讓你的服務器每個請求有 1 個線程。 該線程將為該請求讀取和寫入數據(這就是所有 Web 服務的工作方式,它們通常每個用戶最多可處理 100 個線程)。 性能明智。 有一種叫做線程交換的東西,但不要理會它。
您可以為每個用戶創建一個線程,如上面的鏈接。 或者你可以像 webservice 一樣靜態,每個請求做 1 個線程。
您不應將線程視為抽象的事物,而應更像是一個對象。 如果您總是在一個對象中只保留一個線程,那么“知道”女巫線程在哪里永遠不會有問題。 Ofc 你必須記住鎖和其他東西,但在一個對象中一個線程。
UDP 不保證您的數據包將到達發送它們的位置。 TCP 至少會盡力做到這一點。 因此,為了簡單起見,請使用 TCP。
我只有線索,您可能會不小心使用默認值。
希望這會有所幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.