经过多次失败的研究,我转向这个论坛寻求帮助。
我打算制作一个多客户端 udp 服务器,我的渴望是每个客户端有 1 个线程,并使用阻塞方法:reciveFrom()。为了不错过发送到服务器的任何数据。
我制作了这个测试服务器,它将接收到的数据添加到列表中并再次接收数据。这将是一个测试,看看数据是否会丢失。
测试客户端由 6 个不同数据的套接字组成。当用户单击“全部发送”按钮时将数据发送到服务器。该按钮链接到迭代客户端及其 senddata 方法的 foreach。我按此按钮大约 6 次,服务器列表不会错过任何一条消息。
我的问题是 reciveFrom() 方法如此之快,以至于我需要在我的客户端中有多个线程才能看到它确实丢失了数据,或者这个 reciveFrom() 方法是否完美无缺并且会接收所有数据包?
namespace TestServer
{
class Server
{
List<Data> storage = new List<Data>();
public Server()
{
byte[] data = new byte[1024];
int recv;
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 9050);
socket.Bind(ipep);
IPEndPoint sender = new IPEndPoint(IPAddress.Any,0);
EndPoint remote = (EndPoint)sender;
while (1==1)
{
data = new byte[1024];
recv = socket.ReceiveFrom(data, ref remote);
storage.Add(new Data(recv,data));
}
}
}
struct Data
{
int recv;
byte[] data;
public Data(int recv, byte[] data)
{
this.recv = recv;
this.data = data;
}
}
}
///////////////////////////////////客户////////////// //////////////////////
public partial class Form1 : Form
{
Client[] clients = new Client[6];
TextBox[] txtServerPort = new TextBox[6];
TextBox[] txtServerIP = new TextBox[6];
public Form1()
{
InitializeComponent();
clients[0] = new Client();
clients[1] = new Client();
clients[2] = new Client();
clients[3] = new Client();
clients[4] = new Client();
clients[5] = new Client();
txtServerPort[0] = txtServerPortClient1;
txtServerPort[1] = txtServerPortClient2;
txtServerPort[2] = txtServerPortClient3;
txtServerPort[3] = txtServerPortClient4;
txtServerPort[4] = txtServerPortClient5;
txtServerPort[5] = txtServerPortClient6;
txtServerIP[0] = txtServerIPClient1;
txtServerIP[1] = txtServerIPClient2;
txtServerIP[2] = txtServerIPClient3;
txtServerIP[3] = txtServerIPClient4;
txtServerIP[4] = txtServerIPClient5;
txtServerIP[5] = txtServerIPClient6;
}
private void btnSendDataClient1_Click(object sender, EventArgs e)
{
clients[0].SendData();
}
private void btnSendDataClient2_Click(object sender, EventArgs e)
{
clients[1].SendData();
}
private void btnSendDataClient3_Click(object sender, EventArgs e)
{
clients[2].SendData();
}
private void btnSendDataClient4_Click(object sender, EventArgs e)
{
clients[3].SendData();
}
private void btnSendDataClient5_Click(object sender, EventArgs e)
{
clients[4].SendData();
}
private void btnSendDataClient6_Click(object sender, EventArgs e)
{
clients[5].SendData();
}
private void btnClientsSendData_Click(object sender, EventArgs e)
{
foreach (Client c in clients)
{
c.SendData();
}
}
private void txtServerIPClient1_TextChanged(object sender, EventArgs e)
{
UpdateServerInformation(0);
}
private void txtServerIPClient2_TextChanged(object sender, EventArgs e)
{
UpdateServerInformation(1);
}
private void txtServerIPClient3_TextChanged(object sender, EventArgs e)
{
UpdateServerInformation(2);
}
private void txtServerIPClient4_TextChanged(object sender, EventArgs e)
{
UpdateServerInformation(3);
}
private void txtServerIPClient5_TextChanged(object sender, EventArgs e)
{
UpdateServerInformation(4);
}
private void txtServerIPClient6_TextChanged(object sender, EventArgs e)
{
UpdateServerInformation(5);
}
private void txtServerPortClient1_TextChanged(object sender, EventArgs e)
{
UpdateServerInformation(0);
}
private void txtServerPortClient2_TextChanged(object sender, EventArgs e)
{
UpdateServerInformation(1);
}
private void txtServerPortClient3_TextChanged(object sender, EventArgs e)
{
UpdateServerInformation(2);
}
private void txtServerPortClient4_TextChanged(object sender, EventArgs e)
{
UpdateServerInformation(3);
}
private void txtServerPortClient5_TextChanged(object sender, EventArgs e)
{
UpdateServerInformation(4);
}
private void txtServerPortClient6_TextChanged(object sender, EventArgs e)
{
UpdateServerInformation(5);
}
private void UpdateServerInformation(int index)
{
if (txtServerPort[index].Text.Length > 0)
{
if (txtServerIP[index].Text.Length > 0)
{
clients[index].SetServer(txtServerIP[index].Text, int.Parse(txtServerPort[index].Text));
}
}
}
private void txtDataClient1_TextChanged(object sender, EventArgs e)
{
clients[0].SetData(txtDataClient1.Text);
}
private void txtDataClient2_TextChanged(object sender, EventArgs e)
{
clients[1].SetData(txtDataClient2.Text);
}
private void txtDataClient3_TextChanged(object sender, EventArgs e)
{
clients[2].SetData(txtDataClient3.Text);
}
private void txtDataClient4_TextChanged(object sender, EventArgs e)
{
clients[3].SetData(txtDataClient4.Text);
}
private void txtDataClient5_TextChanged(object sender, EventArgs e)
{
clients[4].SetData(txtDataClient5.Text);
}
private void txtDataClient6_TextChanged(object sender, EventArgs e)
{
clients[5].SetData(txtDataClient6.Text);
}
}
struct ServerInformation
{
IPEndPoint ipep;
public ServerInformation(string ip, int port)
{
ipep = new IPEndPoint(IPAddress.Parse(ip), port);
}
public IPEndPoint GetIPEndPoint()
{
return ipep;
}
}
class Client
{
ServerInformation server;
Socket socket;
byte[] data;
public Client()
{
this.data = new byte[1024]; socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
}
public void SetServer(string ip, int port)
{
server = new ServerInformation(ip, port);
}
public void SetData(string data)
{
this.data = new byte[1024];
this.data = Encoding.ASCII.GetBytes(data);
}
public void SendData()
{
socket.SendTo(data,data.Length,SocketFlags.None, server.GetIPEndPoint());
}
}