我在客户端服务器端工作,对.net和C#不太熟悉,想知道如何将多个客户端连接到同一台服务器。如果可以,我宁愿继续使用TcpClient。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.IO;
using Microsoft.VisualBasic;
using System.Runtime.Serialization.Formatters.Binary;
using System.Threading;
namespace TFServerClient
{
public partial class Form1 : Form
{
private TcpClient client;
public StreamReader STR;
public StreamWriter STW;
public string receive;
public String text_to_send;
TcpListener listener;
public Form1()
{
InitializeComponent();
IPAddress[] localIP = Dns.GetHostAddresses(Dns.GetHostName()); //gets my IP
foreach(IPAddress address in localIP)
{
if(address.AddressFamily == AddressFamily.InterNetwork)
{
txtIPServer.Text = address.ToString();
}
}
}
private void btnStartServer_Click(object sender, EventArgs e)
{
ListenBackground.RunWorkerAsync();
}
private void ReceiveData_DoWork(object sender, DoWorkEventArgs e)
{
while(client.Connected)
{
try
{
receive = STR.ReadLine();
this.txtChat.Invoke(new MethodInvoker(delegate () { txtChat.AppendText("You: " + receive + "\n"); }));
receive = "";
}
catch (Exception x)
{
MessageBox.Show(x.Message.ToString());
}
}
}
private void SendData_DoWork(object sender, DoWorkEventArgs e)
{
if(client.Connected)
{
STW.WriteLine(text_to_send);
this.txtChat.Invoke(new MethodInvoker(delegate () { txtChat.AppendText("Me: " + text_to_send + "\n"); }));
}
else
{
MessageBox.Show("Send failed");
}
SendData.CancelAsync();
}
private async void ListenBackground_DoWork(object sender, DoWorkEventArgs e)
{
this.txtChat.Invoke(new MethodInvoker(delegate () { txtChat.AppendText("Awaiting Connection...\n"); }));
client = listener.AcceptTcpClient();
this.txtChat.Invoke(new MethodInvoker(delegate () { txtChat.AppendText("Client Connected.\n"); }));
STR = new StreamReader(client.GetStream());
STW = new StreamWriter(client.GetStream());
STW.AutoFlush = true;
ReceiveData.RunWorkerAsync(); //Start recieving data in background
SendData.WorkerSupportsCancellation = true; //able to cancel thread
}
private void btnConnect_Click(object sender, EventArgs e)
{
client = new TcpClient();
IPEndPoint IP_End = new IPEndPoint(IPAddress.Parse(txtIPClient.Text), int.Parse(txtPortClient.Text));
try {
client.Connect(IP_End);
if(client.Connected)
{
txtChat.AppendText("Connected To Server " + "\n");
STW = new StreamWriter(client.GetStream());
STR = new StreamReader(client.GetStream());
STW.AutoFlush = true;
ReceiveData.RunWorkerAsync(); //Start recieving data in background
SendData.WorkerSupportsCancellation = true; //able to cancel thread
}
} catch(Exception x)
{
MessageBox.Show(x.Message.ToString());
}
}
private void btnSend_Click(object sender, EventArgs e)
{
if(txtMessage.Text != "")
{
text_to_send = txtMessage.Text;
SendData.RunWorkerAsync();
}
txtMessage.Text = "";
}
}
}
答案 0 :(得分:0)
听起来您只需要多线程化服务器端代码,类似于以下内容:
listener = new TcpListener(ipAddress, portNumber);
listener.Start();
while (true)
{
var client = listener.AcceptTcpClient();
var thread = new Thread(new ThreadStart(() => SOME ACTION));
}
传递给ThreadStart构造函数的委托将处理创建流阅读器和流编写器的问题。它还应该执行您想要执行的任何服务器端业务逻辑。
AcceptTcpClient方法是一种阻塞方法,因此只有在每次从客户端收到TCP请求时才会创建新的Thread实例。
可以找到这种行为的例子:
Here来自csharp.net-informations.com
codeproject.com上的警告:通过在codeproject.com上查看与该文章相关的下载,即表示您同意服务条款和文章许可。许可证是代码项目开放许可证(CPOL)
答案 1 :(得分:-1)
有一个非常好的免费lib,名为NetSockets,您可以使用它。 (https://netsockets.codeplex.com/)<用于下载lib。
lib是TCP和多线程,以下是如何使用它:
创建服务器:
public class MyApp extends Application {
public void start(Stage primaryStage) {
FileChooser configFileChooser = new FileChooser();
File configFile = configFileChooser.showOpenDialog(primaryStage);
// ... parse file and create UI, etc...
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
启动服务器:
static NetObjectServer server = new NetObjectServer();
事件处理程序:
server.Start(IPAddress.Any, 7482);
创建客户端:
server.OnClientAccepted += server_OnClientAccepted;
server.OnClientConnected += server_OnClientConnected;
server.OnClientDisconnected += server_OnClientDisconnected;
server.OnClientRejected += server_OnClientRejected;
server.OnReceived += server_OnReceived;
server.OnStarted += server_OnStarted;
server.OnStopped += server_OnStopped;
事件处理程序:
static readonly NetObjectClient client = new NetObjectClient();
连接:
client.OnConnected += client_OnConnected;
client.OnDisconnected += client_OnDisconnected;
client.OnReceived += client_OnReceived;
此信息取自Joseph Bisaillon的博客(http://www.josephbisaillon.com/)