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
基本上,当选择了一个列表框项目(客户端)时,接收的数据区域将根据该客户端收到的内容而改变。
当选择相同的列表框项(客户端)并发送消息时,它将被发送到该客户端和该客户端(没有多播或类似的东西)。
仅供参考,我将按照相同的原则实施文件传输。
我没有要求你们谦虚的人为我编写我的申请代码,这是徒劳的,我什么都不会学到。我想了解并处理所有这些是如何工作的。很明显,非常非常欢迎能够帮助我理解的代码示例。潜在的问题和疑问:
回到主要问题:在当前状态下,应用程序处理一个客户端。如何让它处理多个客户端?请注意,我选择了多线程,因为我一次连接的客户端数量有限 - 不到10个客户端。
我知道这不是一个我想问的简单问题 - 但每一个答案都将深受赞赏 如果它有所不同,客户端将使用c / cpp,java,python等语言编写,甚至考虑使用PHP。这仅用于学习。但我怀疑这很重要。客户似乎更容易编程,因为逻辑较少,所以我不需要任何帮助。
提前感谢您的任何建议。
答案 0 :(得分:2)
首先,请注明以下链接:http://www.codeproject.com/Articles/429144/Simple-Instant-Messenger-with-SSL-Encryption-in-Cs
现在我会回答你的问题:
没有像#34;太多的线程&#34;。您可以使您的服务器每个请求有1个线程。该线程将读取并为该一个请求写入数据(这是所有Web服务的工作方式,它们通常可以处理每个用户最多100个线程)。表现明智。有一种称为线程交换的东西,但不要打扰它。
您可以为每个用户创建一个主题,例如上面的链接。或者你可以去静态,比如webservices,每个请求做1个帖子。
你应该看一下不像抽象事物的线程,但更像是一个对象。如果你总是只在一个对象中保留一个线程,那么你将永远不会遇到问题&#34;知道&#34;巫婆的线程在哪里。你需要记住锁和东西,但在一个对象中有一个线程。
UDP不保证您的数据包将在它们发送的地方着陆。 TCP至少会尽力做到这一点。为了简单起见,请使用TCP。
我只知道您可能会偶然使用默认值。
希望这会有所帮助。