C# C语言中连接到Udp服务器的客户端列表#
我有一个socket程序,可以与Udp一起工作 我想管理连接到服务器的客户端 例如,如果客户端连接到服务器,则将该客户端添加到列表中。 我已经在Tcp中使用以下代码完成了此操作:C# C语言中连接到Udp服务器的客户端列表#,c#,.net,sockets,udp,client,C#,.net,Sockets,Udp,Client,我有一个socket程序,可以与Udp一起工作 我想管理连接到服务器的客户端 例如,如果客户端连接到服务器,则将该客户端添加到列表中。 我已经在Tcp中使用以下代码完成了此操作: static readonly Dictionary <int, TcpClient> list_clients = new Dictionary <int, TcpClient>(); 提前感谢这段代码对我来说很好用! 服务器: public partial class Server
static readonly Dictionary <int, TcpClient> list_clients = new Dictionary <int, TcpClient>();
提前感谢这段代码对我来说很好用!
服务器:
public partial class Server : Form
{
public Server()
{
InitializeComponent();
}
void Print(string message)
{
listBox1.Items.Add(message);
}
private void button1_Click(object sender, EventArgs e)
{
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
socket.Bind(new IPEndPoint(IPAddress.Loopback, 55555));
byte[] vs = new byte[100];
EndPoint senderRemote = new IPEndPoint(IPAddress.Any, 0);
Dictionary<EndPoint, int> pairs = new Dictionary<EndPoint, int>();
int id = 0;
for (int ii = 0; ii < 5; ii++)
{
socket.ReceiveFrom(vs, ref senderRemote);
if (pairs.ContainsKey(senderRemote))
Print(pairs[senderRemote].ToString() + " says:");
else
{
pairs.Add(senderRemote, id++);
Print("new sender");
}
Print(senderRemote.ToString());
Print(Encoding.Unicode.GetString(vs));
socket.SendTo(vs, senderRemote);
}
}
}
不要忘记客户机和服务器正在通信。因此,他们必须使用折衷的方式进行沟通。如果您想存储客户机信息,它必须是常量。为此,必须将其绑定到固定的localEndPoint
。
您还可以在问题注释中使用解决方案:您可以在消息中添加id。你也可以两者都用。
附言:我使用的是
Socket
类,而不是TCPClient
或UDPClient
,因为我发现它们在某些方面笨拙且不一致。这段代码对我来说很好用!
服务器:
public partial class Server : Form
{
public Server()
{
InitializeComponent();
}
void Print(string message)
{
listBox1.Items.Add(message);
}
private void button1_Click(object sender, EventArgs e)
{
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
socket.Bind(new IPEndPoint(IPAddress.Loopback, 55555));
byte[] vs = new byte[100];
EndPoint senderRemote = new IPEndPoint(IPAddress.Any, 0);
Dictionary<EndPoint, int> pairs = new Dictionary<EndPoint, int>();
int id = 0;
for (int ii = 0; ii < 5; ii++)
{
socket.ReceiveFrom(vs, ref senderRemote);
if (pairs.ContainsKey(senderRemote))
Print(pairs[senderRemote].ToString() + " says:");
else
{
pairs.Add(senderRemote, id++);
Print("new sender");
}
Print(senderRemote.ToString());
Print(Encoding.Unicode.GetString(vs));
socket.SendTo(vs, senderRemote);
}
}
}
不要忘记客户机和服务器正在通信。因此,他们必须使用折衷的方式进行沟通。如果您想存储客户机信息,它必须是常量。为此,必须将其绑定到固定的localEndPoint
。
您还可以在问题注释中使用解决方案:您可以在消息中添加id。你也可以两者都用。
注意:我使用的是
Socket
类,而不是TCPClient
或UDPClient
,因为我发现它们在某些方面笨拙且不一致。UDP是无连接的。您当然可以保留客户端列表,但您必须手动跟踪哪些客户端正在积极发送消息,哪些客户端在X个时间段内没有发送任何消息(和/或收到回复),以便您可以将其从列表中删除。可以相互区分的客户的具体功能是什么?在Tcp中,它们在流中是不同的,可以通过GetStream获得@remy Lebeau由于UDP中没有流,因此可以使用远程IPEndPoint
来区分。否则,让您的UDP消息在其有效负载数据中携带客户标识,例如用户ID、唯一会话cookie等(远程IP:port),在UDP中,me始终是相同的。我以前考虑过的唯一一件事,您也提到过,就是在消息中添加一个id或一定数量。“remoteEP的remoteEP
数据是否总是不同的?”-如果有多个客户端发送到服务器,那么是的。它表示刚刚读取的当前数据包的远程端点。因此,如果您一次从多个客户端获取数据包,remoteEP
将在它们之间切换,因为需要的数据包是无连接的。您当然可以保留客户端列表,但您必须手动跟踪哪些客户端正在积极发送消息,哪些客户端在X个时间段内没有发送任何消息(和/或收到回复),以便您可以将其从列表中删除。可以相互区分的客户的具体功能是什么?在Tcp中,它们在流中是不同的,可以通过GetStream获得@remy Lebeau由于UDP中没有流,因此可以使用远程IPEndPoint
来区分。否则,让您的UDP消息在其有效负载数据中携带客户标识,例如用户ID、唯一会话cookie等(远程IP:port),在UDP中,me始终是相同的。我以前考虑过的唯一一件事,您也提到过,就是在消息中添加一个id或一定数量。“remoteEP的remoteEP
数据是否总是不同的?”-如果有多个客户端发送到服务器,那么是的。它表示刚刚读取的当前数据包的远程端点。因此,如果您一次从多个客户端获取数据包,remoteEP
将根据需要在它们之间切换
public partial class Client : Form
{
public Client()
{
InitializeComponent();
}
Socket socket;
private void button1_Click(object sender, EventArgs e)
{
socket.Send(Encoding.Unicode.GetBytes("Gholamam!"));
byte[] vs = new byte[100];
socket.Receive(vs);
listBox1.Items.Add(Encoding.Unicode.GetString(vs));
}
private void Client_Load(object sender, EventArgs e)
{
socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
socket.Bind(new IPEndPoint(IPAddress.Loopback, new Random().Next(1024,65000)));
socket.Connect(IPAddress.Loopback, 55555);
}
}