PDA

View Full Version : سوال: ارزيابي سرعت دريافت پكت هاي UDP در Win P Cap



elyas_delshadnbe
پنج شنبه 24 مهر 1393, 11:36 صبح
با سلام
بنده دو تا برنامه نوشتم.يكي واسه كلاينت.يكي هم واسه سرور.
كار كلاينت اينه كه بسته هاي 32000 بايتي از نوع udp ايجاد ميكنه و ارسال ميكنه.برنامه كلاينت رو ميشه هم زمان روي چند سيستم اجرا كرد تا بسته هاي زيادي به سمت سرور فرستاده بشه.
سرور كارش اينه كه همه ي بسته هايي كه به سمتش ميان رو دريافت كنه و بر اساس ip بعد از اتمام عمليات دريافت، حجم تمام بسته هايي كه از هر ip رو اومده محاسبه كنه. سرور ip هر بسته رو چك ميكنه و در يك Dictionary ذخيره ميكنه و بسته هاي بعدي كه ميان Dictionary رو چك ميكه و حجم هر بسته جديد رو به حجم بسته هاي ip مربوط به خودش اضافه ميكنه.
تستي كه من انجام ميدم ارسال 100000 بسته 32000 بايتي از 4 كلاينت هست كه سرور در اين حالت نتيجه جالبي رو نشون نميده.
همين تست با 3 تا كلاينت نتايج كاملا رضايت بخشي داره و از هر كلاينت نهايت 1 بسته گم ميشه يني 99999 تا رو دريافت ميكنه.
لطفا اگه ميشه راهنمايي كنين كه مشكل كار از كجاست؟

hamid_hr
پنج شنبه 24 مهر 1393, 12:31 عصر
ببینین udp پروتکلی هست که نمیشه ازش انتظار داشت همه پکیج ها رو درست به مقصد برسونه
اگه محدودیت نداری از Tcp استفاده کن

elyas_delshadnbe
پنج شنبه 24 مهر 1393, 12:34 عصر
حرفت درسته ولي وقتي چك مي كنم با WireShark همه بسته ها ميرسه. چون كلا وسه اين برنامه از 5 سيستم كه با يه سوييچ به هم وصل شدن استفاده مي كنم. يني ترافيك شبكم پايينه

hamid_hr
شنبه 26 مهر 1393, 11:53 صبح
خب یه نمونه کوچولو از برنامه بده ما هم تست کنیم ببینیم چی میشه

elyas_delshadnbe
شنبه 26 مهر 1393, 11:55 صبح
5 تا سيستم دم دست داري كه بتوني تست كني؟

hamid_hr
شنبه 26 مهر 1393, 12:05 عصر
اره
بفرستین کد ها رو هم بچه ها و اساتید ببینن شاید مشکلی رو نونستن حل کنن

elyas_delshadnbe
شنبه 26 مهر 1393, 12:42 عصر
اين كد سرور هست



using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using PcapDotNet.Core;
using PcapDotNet.Packets;
using PcapDotNet.Base;
using PcapDotNet.Core.Extensions;
using System.Threading;


namespace FormUDPServer
{
public partial class Win_P_Cap : Form
{
private IList<LivePacketDevice> allDevices = LivePacketDevice.AllLocalMachine;
private PacketDevice selectedDevice;
private Thread TH_Receive_Start;
private string SourceIP;
private byte[] array = new byte[4];
private Dictionary<string, uint> Dic_ReceiveData = new Dictionary<string, uint>();


public Win_P_Cap()
{
InitializeComponent();


if (allDevices.Count == 0)
{
LiB__Select_Dev.Items.Add("No interfaces found! Make sure WinPcap is installed.");
return;
}


// Print the list
for (int i = 0; i != allDevices.Count; ++i)
{
LivePacketDevice device = allDevices[i];
LiB__Select_Dev.Items.Add((i + 1) + ". " + device.Description);
}
}


// Callback function invoked by Pcap.Net for every incoming packet
private void Btn_OK_Click(object sender, EventArgs e)
{
string Lib_Selected;
string[] Dev_Selected;
int deviceIndex = 0;


if (LiB__Select_Dev.SelectedItems.Count != 0)
{
Lib_Selected = (LiB__Select_Dev.SelectedItem.ToString());
Dev_Selected = Lib_Selected.Split('.');
}
else
{
MessageBox.Show("Select A Device Please!!!");
return;
}
// Retrieve the device list from the local machine
do
{
if (!int.TryParse(Dev_Selected[0], out deviceIndex) ||
deviceIndex < 1 || deviceIndex > allDevices.Count)
{
deviceIndex = 0;
}
} while (deviceIndex == 0);


// Take the selected adapter
selectedDevice = allDevices[deviceIndex - 1];


TH_Receive_Start = new Thread(Receive_Start);
TH_Receive_Start.Start();


}


private void Receive_Start()
{
AppendTextBox("");
// Open the device
using (PacketCommunicator communicator =
selectedDevice.Open(65536, // portion of the packet to capture
// 65536 guarantees that the whole packet will be captured on all the link layers
PacketDeviceOpenAttributes.Promiscuous, // promiscuous mode
1000)) // read timeout
{
AppendTextBox("Listening on " + selectedDevice.Description + "...");
// start the capture
communicator.ReceivePackets(0, PacketHandler);


}
}


private void PacketHandler(Packet packet)
{
if ((uint)packet.Buffer[23] == 17
&& (packet.Ethernet.IpV4.Source.ToString() == ("192.168.1.10")
|| packet.Ethernet.IpV4.Source.ToString() == ("192.168.1.20")
|| packet.Ethernet.IpV4.Source.ToString() == ("192.168.1.100")
|| packet.Ethernet.IpV4.Source.ToString() == ("192.168.1.11")
|| packet.Ethernet.IpV4.Source.ToString() == ("192.168.1.103")
|| packet.Ethernet.IpV4.Source.ToString() == ("192.168.1.49")))
{
for (int i = 0; i <= 3; i++)
SourceIP += packet.Buffer[i + 26].ToString();
if (!Dic_ReceiveData.ContainsKey(SourceIP))
Dic_ReceiveData.Add(SourceIP, 0);
if (packet.Buffer[21] == 00)
Dic_ReceiveData[SourceIP] += (uint)packet.Buffer.Length - 42;
else
Dic_ReceiveData[SourceIP] += (uint)packet.Buffer.Length - 34;
SourceIP = "";
}
}


private void AppendTextBox(string value)
{
if (InvokeRequired)
{
this.Invoke(new Action<string>(AppendTextBox), new object[] { value });
return;
}
if (Txt_Receive_Data.Lines.Length == 100)
Txt_Receive_Data.AppendText("");
Txt_Receive_Data.AppendText(value + "\r\n");
}


private void Win_P_Cap_FormClosing(object sender, FormClosingEventArgs e)
{
try
{
TH_Receive_Start.Abort();
}
catch
{
AppendTextBox("Error Accured In Aborting TH");
}
}


private void Btn_ShowResult_Click(object sender, EventArgs e)
{
TH_Receive_Start.Abort();
Txt_Receive_Data.Text = "";
foreach (var IPCount in Dic_ReceiveData)
{
Txt_Receive_Data.Text += IPCount.Key + ": " + IPCount.Value + "\r\n";
}
Dic_ReceiveData.Clear();
}
}
}

elyas_delshadnbe
شنبه 26 مهر 1393, 12:43 عصر
اينم كد كلاينت هست



using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Diagnostics;


namespace FormUDPClient
{
public partial class UDPClient : Form
{
private Boolean exception_thrown = false;
private bool Continue = true;
private int Start_Num = 0;
private int End_Num = 0;
private byte[] final_send_buffer;
private IPAddress send_to_address;
private IPEndPoint sending_end_point;
private Socket sending_socket;
private Thread send;
private bool StartSend = true;
private bool StopSend = true;


public UDPClient()
{
InitializeComponent();
}


private void Btn_Start_Click(object sender, EventArgs e)
{
StopSend = false;
if (StartSend == true)
{
//Txt_Result.Text = "";
Txt_Result.Text = "broadcat started" + "\r\n";
Continue = true;
bool operationfailed = true;
send_to_address = IPAddress.Parse(Txt_IPAddress.Text);
sending_socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
if (Txt_IPAddress.Text == "")
{
operationfailed = false;
MessageBox.Show("Please Enter Server IP");
}
else
{
send_to_address = IPAddress.Parse(Txt_IPAddress.Text);
sending_end_point = new IPEndPoint(send_to_address, 11000);
}
if (Txt_EndNum.Text == "")
{
operationfailed = false;
MessageBox.Show("Please Enter End Number");
}
else
{
Int32.TryParse(Txt_StartNum.Text, out Start_Num);
Int32.TryParse(Txt_EndNum.Text, out End_Num);
}
if (Txt_SizeOfArray.Text == "")
{
operationfailed = false;
MessageBox.Show("please enter size of array");
}
else
final_send_buffer = new byte[int.Parse(Txt_SizeOfArray.Text)];
if (operationfailed == true && Continue == true)
{
send = new Thread(StartSending);
send.Start();
}
StartSend = false;
}
}


private void AppendTextBox(string value)
{
if (InvokeRequired)
{
this.Invoke(new Action<string>(AppendTextBox), new object[] { value });
return;
}
Txt_Result.Text = value;
}


private void StartSending()
{
for (int i = 0; i < final_send_buffer.Length; i++)
final_send_buffer[i] = 1;
//var watch = Stopwatch.StartNew();
while (Continue && Start_Num != End_Num + 1)
{
AppendTextBox("sending to address, " + sending_end_point.Address + " ," + sending_end_point.Port + " ," + Start_Num + "\r\n");
try
{
sending_socket.SendTo(final_send_buffer, sending_end_point);
}
catch (Exception send_exception)
{
exception_thrown = true;
Console.WriteLine(" Exception {0}", send_exception.Message);
}
Start_Num++;
}
//watch.Stop();
AppendTextBox(Convert.ToString(Start_Num));
}


private void Btn_Stop_Click(object sender, EventArgs e)
{
if (StopSend == false)
{
Continue = false;
try
{
send.Abort();
}
catch
{
//Txt_Result.Text = "kar kherabes";
}
try
{
sending_socket.Close();
}
catch
{
//Txt_Result.Text = "kar kherabes";
}
}
StopSend = true;
StartSend = true;
}


private void UDPClient_FormClosing(object sender, FormClosingEventArgs e)
{
try
{
send.Abort();
}
catch
{
//Txt_Result.Text = "kar kherabes";
}
try
{
sending_socket.Close();
}
catch
{
//Txt_Result.Text = "kar kherabes";
}
}
}
}

joker
شنبه 26 مهر 1393, 15:42 عصر
در پکت udp شما یک پردازش ناگهانی ، یک تایم اوت در سیستم کلاینت را سرور یا سوئیچ هم داشته باشی میتونه منجر به از دست رفتن پکت بشه کاریش هم نمیتونی بکنی
خود دریافت و ارسال پکت هم بار پردازشی روی سیستمتون داره... سیستم عامل صف دریافت درخواستها را تشکیل میده و هزارتا قرواطفار پشت این داستانه ،
وقتی 100 هزارتا پکت پشت سر هم میفرستی هر اتفاقی در واحد زمان ممکنه بیفته ، اگه همین کارو با 10 تا سیستم انجام بدی پکت لاست یهو میبینی به جای دو برابر ، 20برابر میشه..

elyas_delshadnbe
یک شنبه 27 مهر 1393, 09:27 صبح
در پکت udp شما یک پردازش ناگهانی ، یک تایم اوت در سیستم کلاینت را سرور یا سوئیچ هم داشته باشی میتونه منجر به از دست رفتن پکت بشه کاریش هم نمیتونی بکنی
خود دریافت و ارسال پکت هم بار پردازشی روی سیستمتون داره... سیستم عامل صف دریافت درخواستها را تشکیل میده و هزارتا قرواطفار پشت این داستانه ،
وقتی 100 هزارتا پکت پشت سر هم میفرستی هر اتفاقی در واحد زمان ممکنه بیفته ، اگه همین کارو با 10 تا سیستم انجام بدی پکت لاست یهو میبینی به جای دو برابر ، 20برابر میشه..

پس من هر چي كارت شبكه و رسانه انتقالمم قوي كنم به هر حال ديتا لاست خواهم داشت ديگه؟

joker
یک شنبه 27 مهر 1393, 13:03 عصر
پس من هر چي كارت شبكه و رسانه انتقالمم قوي كنم به هر حال ديتا لاست خواهم داشت ديگه؟

بله ، احتمال پکت لاست همیشه هست ( حتی در نوع tcp هم که اساسا بر اساس udp پکتها رد و بدل میشن پکت لاست هست منتها چون تاییده پکتها بین دو طرف مرتب انجام میشه بعد از هر پکت لاست مجددا ارسال میشه و از دید کاربر یک ارتباط بدون از دست رفتن دیتا دیده میشه ) ولی در لایه شبکه این گم شدن پکتها چیز غیرعادی نیست
شما یک sleep 10 میلی ثانیه ای در برنامه ات اضافه کن به عنوان یک باگ مجازی ببین چه بلایی سر پکتهای گمشده میاد :لبخند:

elyas_delshadnbe
یک شنبه 27 مهر 1393, 13:20 عصر
آره ميدونم.
ي سوال دارم.برنامه سرور من رو متوجه شدين؟ بافري كه سرور بسته هاي udp دريافتي رو براي پردازش توش ذخيره ميكنه چطور ميتونم سايزش رو بالا ببرم؟

joker
یک شنبه 27 مهر 1393, 19:57 عصر
شما در پروتکل IP باید استاندارد کار کنید ، چقدر میخواین زیاد کنید ؟ از ی حدی زیادتر بشه طول پکت ، موقع خروج از سیستم میشکنه و شاید اصلا به مقصد نرسه ( از خوای روتر و مسیریاب ها ( همون سوئیچی که داریداستفاده میکنید برای شبکه کردن)
در IP v4 حداکثر سایز اسمی 65 کیلوبایته (http://www.infocellar.com/networks/ip/ip-packet.htm)
افزایش سایز پکت هم خودش بازهم بارپردازشی بیشتری روی سیستم شما خواهد داشت. ( استفاده از منابع حافظه برای پردازش)

elyas_delshadnbe
دوشنبه 28 مهر 1393, 10:10 صبح
شما در پروتکل IP باید استاندارد کار کنید ، چقدر میخواین زیاد کنید ؟ از ی حدی زیادتر بشه طول پکت ، موقع خروج از سیستم میشکنه و شاید اصلا به مقصد نرسه ( از خوای روتر و مسیریاب ها ( همون سوئیچی که داریداستفاده میکنید برای شبکه کردن)
در IP v4 حداکثر سایز اسمی 65 کیلوبایته (http://www.infocellar.com/networks/ip/ip-packet.htm)
افزایش سایز پکت هم خودش بازهم بارپردازشی بیشتری روی سیستم شما خواهد داشت. ( استفاده از منابع حافظه برای پردازش)

درسته. من وقتي بسته 32000 بايتي ميفرستم اين بسته ها حدودا به 22 تا بسته 1514 تايي تبديل ميشه به علاوه يه بسته ي 964 تايي. كه اينا به خاطر ظرفيت بسته هاي udp هست. من ميخوام بدونم آيا با تغيير سايز بافر server ميشه اين data lost رو كمتر كرد و اگه ميشه چطور ميشه اين كار رو انجام داد؟

joker
دوشنبه 28 مهر 1393, 11:41 صبح
علت گم شدن پکتها بحث سایز پکتها نیست حتی یک وقفه سیستمی ساده هم میتونه منجر به از دست دادن پکت بشه
کلا اگه مشکل پکت لاست داری پروتکل UDP را ببوس بزار کنار چون تضمینی روش نیست نبوده نخواهد بود.

پیوست : در رابطه با شکسته شدن به سایزهای کوچکتر( حدود 1 کیلوبایت) مشکل درایور ویندوز هست این لینک را ببین
http://support.microsoft.com/kb/2465285

elyas_delshadnbe
دوشنبه 28 مهر 1393, 12:26 عصر
علت گم شدن پکتها بحث سایز پکتها نیست حتی یک وقفه سیستمی ساده هم میتونه منجر به از دست دادن پکت بشه
کلا اگه مشکل پکت لاست داری پروتکل UDP را ببوس بزار کنار چون تضمینی روش نیست نبوده نخواهد بود.

پیوست : در رابطه با شکسته شدن به سایزهای کوچکتر( حدود 1 کیلوبایت) مشکل درایور ویندوز هست این لینک را ببین
http://support.microsoft.com/kb/2465285

درسته udp از اين لحاظا عتباري بهش نيست. ولي اين كار لازمه كه با udp انجام بشه. سيستم اصلي كه داده ميفرسته udp ان. و چاره ي ديگه اي ندارم.سايز بافر رو نگفتين ميتونم افزايش بدم؟

joker
دوشنبه 28 مهر 1393, 12:40 عصر
بله ، تا ظرفیتی که سیستم عاملتون اجازه بده میتونید افزایش بدین
نیاز به تغییرات در تنظیمات سیستم عامل هر دو طرف هست و اطمینان از اینکه سوئیچ شما پکتها را نمیشکنه به سایزهای کوچکتر

فایل ضمیمه را ببینید.

elyas_delshadnbe
دوشنبه 28 مهر 1393, 12:47 عصر
بله ، تا ظرفیتی که سیستم عاملتون اجازه بده میتونید افزایش بدین

دقيقا كارت شبكه منم يه چيز خفن بود. jumbo رو روي 9014 تنظيم كردم و receive rate رو هم روي 2048 فك كنم تنظيم كردم. همش ماكزيمم.
پس با اين تفاسير بايد دنبال يه وي»گي سريعتر يا يه كار بهتر تو Win P Cap باشم. نظرتون چيه؟

elyas_delshadnbe
سه شنبه 29 مهر 1393, 13:25 عصر
اساتيد؟كجايين؟