PDA

View Full Version : حرفه ای: ارسال و دریافت دیتا(صدا) از طریق UDP Protocol در C#.NET 4.5



General-Xenon
یک شنبه 11 مرداد 1394, 06:32 صبح
سلام وقت بخیر، قبل مطرح کردن مسئله، اگر تاپیک در جایی نامناسب ایجاد شده، پوزش می طلبم (تا جایی که تشخیص دادم بخش مرتبط اینجاست )

بنده طی پروژه ای طرح نوشتن یک کنفرانس از طریق اینترنت رو دارم که در این برنامه باید صدا رو از ( گوینده ) دریافت و برای چند کلاینت پخش کنم ، تمام اطلاعات اولیه نوشته شده و به راحتی از طریق TCP Protocol این ارتباط برقرار است، متاسفانه برای ارسال صدا طی تحقیقاتی که کردم، UDP Protocol رو پیشنهاد دادند بخاطر سرعت ارسال اطلاعات و ....

حال کمکی که از دوستان دارم، آیا برای ارسال صدا لزوما باید از UDP استفاده کرد ؟
مکانیزم ارسال و دریافت در کلاینت به چه صورت هست ؟
( دریافت در سرور انجام میشه اما ارسال به کلاینت های دیگه به چه صورته ؟ آیا باید (کد سرور) در کلاینت نوشته بشه ؟ آیا مکانیزم UDP بصورت TCP Socket هست ؟ )

پیشاپیش، تشکر

zayens
یک شنبه 11 مرداد 1394, 09:49 صبح
حال کمکی که از دوستان دارم، آیا برای ارسال صدا لزوما باید از UDP استفاده کرد ؟

خیر راه های دیگری نیز وجود دارد مثل TCP



دریافت در سرور انجام میشه اما ارسال به کلاینت های دیگه به چه صورته ؟ آیا باید (کد سرور) در کلاینت نوشته بشه ؟ آیا مکانیزم UDP بصورت TCP Socket هست ؟


ببینید اگر از پروتکل های نظیر UDP استفاده میکنید ابدا نیاز به گذاشتن Listen ندارید. کافیه از متد ReceiveFrom (https://msdn.microsoft.com/en-us/library/system.net.sockets.socket.receivefrom.aspx)
برای دریافت هاتون استفاده کنید

مثال برای ریسیو فرام:
public static void ReceiveFrom4(){
IPHostEntry hostEntry = Dns.GetHostEntry(Dns.GetHostName());
IPEndPoint endPoint = new IPEndPoint(hostEntry.AddressList[0], 11000);


Socket s = new Socket(endPoint.Address.AddressFamily,
SocketType.Dgram,
ProtocolType.Udp);


// Creates an IpEndPoint to capture the identity of the sending host.
IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
EndPoint senderRemote = (EndPoint)sender;


// Binding is required with ReceiveFrom calls.
s.Bind(endPoint);
byte[] msg = new Byte[256];
Console.WriteLine ("Waiting to receive datagrams from client...");
// This call blocks.
s.ReceiveFrom(msg, 0, msg.Length, SocketFlags.None, ref senderRemote);
s.Close();
}

اما اگه از TCP استفاده میکنید که اونوقت TcpClient (https://msdn.microsoft.com/en-us/library/system.net.sockets.tcpclient.aspx), TcpListener (https://msdn.microsoft.com/en-us/library/system.net.sockets.tcplistener.aspx) کاره تون رو راه میندازه


به این کلاس یه نگاه بنداز
public class GetSocket{
private static Socket ConnectSocket(string server, int port)
{
Socket s = null;
IPHostEntry hostEntry = null;


// Get host related information.
hostEntry = Dns.GetHostEntry(server);


// Loop through the AddressList to obtain the supported AddressFamily. This is to avoid
// an exception that occurs when the host IP Address is not compatible with the address family
// (typical in the IPv6 case).
foreach (IPAddress address in hostEntry.AddressList)
{
IPEndPoint ipe = new IPEndPoint(address, port);
Socket tempSocket =
new Socket(ipe.AddressFamily, SocketType.Stream, ProtocolType.Tcp);


tempSocket.Connect(ipe);


if (tempSocket.Connected)
{
s = tempSocket;
break;
}
else
{
continue;
}
}
return s;
}


// This method requests the home page content for the specified server.
private static string SocketSendReceive(string server, int port)
{
string request = "GET / HTTP/1.1\r\nHost: " + server +
"\r\nConnection: Close\r\n\r\n";
Byte[] bytesSent = Encoding.ASCII.GetBytes(request);
Byte[] bytesReceived = new Byte[256];


// Create a socket connection with the specified server and port.
Socket s = ConnectSocket(server, port);


if (s == null)
return ("Connection failed");


// Send request to the server.
s.Send(bytesSent, bytesSent.Length, 0);


// Receive the server home page content.
int bytes = 0;
string page = "Default HTML page on " + server + ":\r\n";


// The following will block until te page is transmitted.
do
{
bytes = s.Receive(bytesReceived, bytesReceived.Length, 0);
page = page + Encoding.ASCII.GetString(bytesReceived, 0, bytes);
}
while (bytes > 0);


return page;
}


public static void Main(string[] args)
{
string host;
int port = 80;


if (args.Length == 0)
// If no server name is passed as argument to this program,
// use the current host name as the default.
host = Dns.GetHostName();
else
host = args[0];


string result = SocketSendReceive(host, port);
Console.WriteLine(result);
}
}

این کلاس یه مثالیه برای ارسال دیتا به سرور HTTP و دریافت دیتا

General-Xenon
یک شنبه 11 مرداد 1394, 19:06 عصر
سلام مجدد خدمت شما و تشکر بابت راهنمایی، سوالی داشتم از جنابعالی

اینکه من در طراحی این سیستم، برای ارتباط جانبی Text یا .... از TCP Socket استفاده کردم... مکانیزم برنامه به این صورت هست که کاربر با استفاده از TCP Socket به سرور در یک Port اتصال برقرار میکند، سپس این سوکت برقرار شده و من این سوکت برقرار شده ما بین سرور و کلاینت رو در یک لیست به عنوان درگاه ارتباطی کاربر با سرور نگهداری میکنم تا هرازچند کاهی اطلاعات به این کلاینت از سرور ارسال بشه، آیا الزاما پس از برقرار و ارسال هر Packet باید این سوکت ها بسته شوند یا این مکانیزمی که خودم درست کردم صحیح هست ؟

و اما در مورد سئوالی که در ابتدا مطرح کردم، من در ارسال از کلاینت به سرور مشکلی ندارم، دقیقا یک Listner در سرور تعریف کردم و همان Listner کار ارسال رو انجام میده، مشکل اصلی بنده ارسال از سرور به کلاینت هست که هنگامی که سرور تصمیم به ارسال گرفته، تشخیص نمیده که به چه پورتی در آدرس Endpoint کلاینت ارسال این Packet ها رو انجام بده...

zayens
دوشنبه 12 مرداد 1394, 10:48 صبح
سلام مجدد خدمت شما و تشکر بابت راهنمایی، سوالی داشتم از جنابعالی

اینکه من در طراحی این سیستم، برای ارتباط جانبی Text یا .... از TCP Socket استفاده کردم... مکانیزم برنامه به این صورت هست که کاربر با استفاده از TCP Socket به سرور در یک Port اتصال برقرار میکند، سپس این سوکت برقرار شده و من این سوکت برقرار شده ما بین سرور و کلاینت رو در یک لیست به عنوان درگاه ارتباطی کاربر با سرور نگهداری میکنم تا هرازچند کاهی اطلاعات به این کلاینت از سرور ارسال بشه، آیا الزاما پس از برقرار و ارسال هر Packet باید این سوکت ها بسته شوند یا این مکانیزمی که خودم درست کردم صحیح هست ؟

و اما در مورد سئوالی که در ابتدا مطرح کردم، من در ارسال از کلاینت به سرور مشکلی ندارم، دقیقا یک Listner در سرور تعریف کردم و همان Listner کار ارسال رو انجام میده، مشکل اصلی بنده ارسال از سرور به کلاینت هست که هنگامی که سرور تصمیم به ارسال گرفته، تشخیص نمیده که به چه پورتی در آدرس Endpoint کلاینت ارسال این Packet ها رو انجام بده...

در مورد سوال اول که مشکل مربوط به تنظیمات شبکه است
برای تست یک برنامه عادی ارسال متن «چت» (سرور و کلاینت) دانلود کنید و کار کنید تا تنظیمات اتصال و آی پی ها رو بدست بیارید

در مورد سوال دومتون خب بستگی به کارتون داره
گاهی لازمه دیتایی که به کلاینت نرسیده ذخیره بشه تا کاربر بعدا در موقع برقراری ارتباط از اون طریق بگیره (ینی اونجا دیگه بحث سوکت پروگرمینگ نیست و ادامه کار با کانکشن کلاینت و سرور (حالا یا sql یا path) یا ... دیتا گرفته میشه)