PDA

View Full Version : حرفه ای: کانکت شدن همزمان چندین کلاینت به سرور در سوکت پروگرامینگ



EhsanAvr
سه شنبه 30 آذر 1389, 22:57 عصر
سلام دوستان میخواستم بدونم آیا در سوکت پروگرامینگ این امکان وجود داره که چندین کلاینت به صورت همزمان به سرور کانکت بشن و بشه به صورت جداگانه با هرکدام از کلاینت ها تبادل اطلاعات کرد؟
اگر چنین امکانی وجود داره چطور میشه این کار رو انجام داد؟

EhsanAvr
پنج شنبه 02 دی 1389, 16:59 عصر
دوستان کجایین:افسرده:

EhsanAvr
یک شنبه 05 دی 1389, 23:04 عصر
کسی نیست جواب بده یک هفته گذشت:گریه:

abbas.oveissi
یک شنبه 05 دی 1389, 23:34 عصر
آره ، معلومه میشه :لبخند: اگه نشه که باید #C رو بندازن دور . البته بگو رو اینترنت میخوای یا شبکه محلی ؟؟؟

Reza_Yarahmadi
دوشنبه 06 دی 1389, 07:20 صبح
توي لينك زير يه برنامه چت گذاشتم ، يك نگاه به برنامه سرور اون بندازيد ، فكر كنم كارتون رو راه بندازه.
در صورتي هم كه مشكلي بود در خدمتتون هستم.
http://barnamenevis.org/showthread.php?t=260525

EhsanAvr
دوشنبه 06 دی 1389, 18:52 عصر
برای شبکه محلی میخوام.ممنون از کمک دوستان

abbas.oveissi
سه شنبه 07 دی 1389, 02:23 صبح
برای شبکه محلی میخوام.ممنون از کمک دوستان

اگر با threads ها آشنایی داشته باشی که کاری برات نداره . اگه یکم انگلیسی بلد باشه با لینک زیر به راحتی همشو یاد میگیری،خودش سورس ها رو هم داره برای دانلود :

لینک آموزش و سورس برنامه (http://www.geekpedia.com/tutorial239_Csharp-Chat-Part-1---Building-the-Chat-Client.html)

amatur_barnamenevis
چهارشنبه 25 خرداد 1390, 11:46 صبح
سلام
من يه مشكل دارم اونم اينكه وقتي يه برنامه كلاينت ميخواد وصل بشه به سرور برنامه هنگ ميكنه اين در حالتي هستش كه قبلا يه برنامه كلاينت به سرور هست و مي تونه بهش متن ارسال كنه و متن ارساليش رو دوباره ببينه ولي وقتي دومين كلاينت ميخواد وصل بشه و دكمه اتصال رو ميزنم فرمش ميره توي هنگ اينم كد سمت سرور هستش اگه كد كلاينت لازمه اونم بذارم؟؟

//Run Servet
private void button2_Click(object sender, EventArgs e)
{
MessageBox.Show("Server IP Address:" + ip + " Port Number: " + pi.Port, "Your Setting is Set", MessageBoxButtons.OK);
connection = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
connection.Bind(pi);
connection.Listen(10);
Thread nakh1 = new Thread(new ThreadStart(listening));
nakh1.Start();
run.Enabled = false;
serverconnect.Text = "Connection is Connected";

}

private void listening()
{
newclient = connection.Accept();
client = (IPEndPoint)newclient.RemoteEndPoint;
newclient.Send(msgserver);
Thread nakh2 = new Thread(new ThreadStart(daterecieve));
nakh2.Start();
}
private void daterecieve()
{

while (true)
{
while (true)
{
length = newclient.Receive(data);
if (length > 0)
{
text = System.Text.Encoding.UTF8.GetString(data, 0, length);
text2 = Encoding.ASCII.GetBytes(text);
newclient.Send(text2);
break;
}

}
fillTextBox(text);
}
}

saman6384
چهارشنبه 25 خرداد 1390, 12:27 عصر
1. دکمه اتصال رو تو سرور میزنی یا کلاینت؟

2.چرا فقط یه کلاینت تعریف کردی؟ مگه نمی خوای 2 تا کلاینت وصل بشن؟
یه آرایه چندتایی از سوکت واسه کلاینت هات تعریف کن!

amatur_barnamenevis
چهارشنبه 25 خرداد 1390, 16:26 عصر
سرور يه دكمه اتصال داره كه اتصال رو برقرار ميكنه تا كلاينتها بتونن خودشونو به سرور وصل كنن كلاينتها هم دكمه اتصال دارن.
آرايه كلاينتها چطوريه؟؟ يعني چي دقيقا؟؟
مگه اون خط 7 ( connection.Listen(10);) اينكارو نميكنه ؟؟؟
من دقيقا متوجه نشدم بايد چي كار كنم؟؟

saman6384
چهارشنبه 25 خرداد 1390, 17:07 عصر
1. دکمه اتصال رو تو سرور یه بار میزنی دیگه؟

2. اینجوری که شما برنامتو نوشتی کلا یدونه کلاینت قبول میکنه!!
اگه می خوای چنتاش کنی باید تابع listening رو اینجوری کنی :

for (int i = 0; i < 10; i++)
{
newclient = connection.Accept();
client = (IPEndPoint)newclient.RemoteEndPoint;
newclient.Send(msgserver);
Thread nakh2 = new Thread(new ThreadStart(daterecieve));
nakh2.Start();
}
اینجوری میتونی 10 تا کلاینت بگیری

اما یه مشکلی داره!
هر دفه که یه کلاینت وصل میشه! به جای اینکه یه سوکت جدید واسش درس کنی! میریزی تو کلاینت قبلی!! ینی عملا داری کلاینت های قبلی رو قط میکنی!!

واسه تصحیحش :

System.Net.Sockets.Socket[] newclient;
اینجوری تعریفش کن

در آخر یه همچین چیزی میشه :

private void listening()
{
for (int i = 0; i < 10; i++)
{
newclient[i] = connection.Accept();
client[i] = (IPEndPoint)newclient[i].RemoteEndPoint;
newclient[i].Send(msgserver);
if (i != 0) continue;
Thread nakh2 = new Thread(new ThreadStart(daterecieve));
nakh2.Start();
}

}

amatur_barnamenevis
چهارشنبه 25 خرداد 1390, 18:47 عصر
1-آره
سامان جان متوجه شدم حالا ولي نميدونم بايد چه طوري اين قسمت رو تغيير بدم؟؟؟ ميشه راهنمايي كني؟؟
private void daterecieve()
{

while (true)
{
while (true)
{
length = newclient.Receive(data);
if (length > 0)
{
text = System.Text.Encoding.UTF8.GetString(data, 0, length);
text2 = Encoding.ASCII.GetBytes(text);
newclient.Send(text2);
break;
}

}
fillTextBox(text);
}
}

amatur_barnamenevis
چهارشنبه 25 خرداد 1390, 19:04 عصر
سامان جان اين آخرين تغييرات منه ولي بازم جواب نداد
private void listening()
{
for (i = 0; i < 10; i++)
{
newclient[i] = connection.Accept();
client[i] = (IPEndPoint)newclient[i].RemoteEndPoint;
newclient[i].Send(msgserver);
if (i != 0) continue;
Thread nakh2 = new Thread(new ThreadStart(daterecieve));
nakh2.Start();
}
}
private void daterecieve()
{
for (j = 0; j < 10;j++)
{
while (true)
{
while (true)
{
length = newclient[j].Receive(data);
if (length > 0)
{
text = System.Text.Encoding.UTF8.GetString(data, 0, length);
text2 = Encoding.ASCII.GetBytes(text);
newclient[j].Send(text2);
break;
}

}
fillTextBox(text);
}
}
}

راستي توي خط 15 warning داده كه Unreachable code detect زير j++ خط سبز گذاشته؟؟

saman6384
چهارشنبه 25 خرداد 1390, 21:22 عصر
1-آره
سامان جان متوجه شدم حالا ولي نميدونم بايد چه طوري اين قسمت رو تغيير بدم؟؟؟ ميشه راهنمايي كني؟؟
private void daterecieve()
{

while (true)
{
while (true)
{
length = newclient.Receive(data);
if (length > 0)
{
text = System.Text.Encoding.UTF8.GetString(data, 0, length);
text2 = Encoding.ASCII.GetBytes(text);
newclient.Send(text2);
break;
}

}
fillTextBox(text);
}
}

خوب برای هر کدوم از کلاین هات باید یه ترد جدا راه بندازی دیگه!! ( الان این به نظرم میرسه)

saman6384
چهارشنبه 25 خرداد 1390, 21:26 عصر
خوب عزیزم نبایدم جواب بده!

راس میگه دیگه بدبخت!! وقتی از while خارج نمیشه j++ هیچ وقت انجام نمیشه دیگه!!

ترد دریافتتو درس کن!
بعد اگه بازم مشکلی بود بگو خطاش چیه ردیفش میکنیم :چشمک:

یه سرچ هم بزن تو گوگول به اسمه C# chatroom sample کلی مثال گیرت میاد!

amatur_barnamenevis
چهارشنبه 25 خرداد 1390, 21:30 عصر
من قاطي كردم به خدا.
مثال دارم از اينترنت ولي يكي دوتشون همين مشكل وصل چندتايي به سرور رو دارن
newclient آرايست.
الان من بايد چطوري باز دوباره thred بذارم؟؟؟:متعجب:
من for رو بعد از while دوم گذاشتم جواب داد يعني تونستم با چندتا كلاينت ارتباط برقرار كنم ولي send و receive ندارم

saman6384
چهارشنبه 25 خرداد 1390, 22:54 عصر
System.Threading.Thread[] t;

اینجوری ترد هاتو بساز!

نه عزیزم
اون for که گذاشتی کلا اشتباس!!!!
ببین هر وقت خط دستور به newclient[j].Receive(data); میرسه ، منتظر میمونه تا یچیزی از کلاینت دریافت کنه ، تا وقتیم که دریافت نکنه همونجا میمونه
در نتیجه تا کلاینت یک چیزی نفرسته سراغ دریافت از دومی نمیره ..... و الا آخر

شما واسه هر کدوم یه ترد بزار
کارت راه میوفته

amatur_barnamenevis
پنج شنبه 26 خرداد 1390, 22:56 عصر
سامان جان من شرمندم نميدونم چي كار كنم يكم گيج شدم
واقعيتش اينه كه نميدونم بايد چطوري براي هر كلاينت ترد جدا در نظر بگيرم؟؟ميشه يه كمك بكني؟؟
نميدونم بايد چي كار كنم چطوري بايد ترد جداگونه براشون بذارم يا كجا بذارم.
الان بايد توي for همون listen ترد بسازم؟؟؟
من اينطوري كردم
private void listening()
{
for (i = 0; i < 10; i++)
{
newclient[i] = connection.Accept();
client[i] = (IPEndPoint)newclient[i].RemoteEndPoint;
newclient[i].Send(msgserver);
if (i != 0) continue;

nakh2[i] = new Thread(new ThreadStart(daterecieve));
nakh2[i].Start();
}
}
private void daterecieve()
{

while (true)
{

while (true)
{

length = newclient[i].Receive(data);
if (length > 0)
{
text = System.Text.Encoding.UTF8.GetString(data, 0, length);
text2 = Encoding.ASCII.GetBytes(text);
newclient[i].Send(text2);
break;
}

}
fillTextBox(text);
}

}
ولي زمان اجرا روي خط 10 ايراد ميگيره.
ببخشيد ديگه يكم آماتورم

saman6384
پنج شنبه 26 خرداد 1390, 23:18 عصر
خوب چه خطایی؟؟

تو خط 23 ، i رو از کجا بهش میدی؟

amatur_barnamenevis
جمعه 27 خرداد 1390, 08:54 صبح
سامان جان اين آخرين تغييراتمه ببين اينطوري شد
private void daterecieve()
{

while (true)
{

while (true)
{
for (int j = 0; j < 10; j++)
{
length = newclient[j].Receive(data);
if (length > 0)
{
text = System.Text.Encoding.UTF8.GetString(data, 0, length);
text2 = Encoding.ASCII.GetBytes(text);
newclient[j].Send(text2);
break;
}
}
fillTextBox(text);
}

}

}
الان وقتي كلاينت دوم كانكت رو ميزنه متصل ميشه و از سرور براش پيغام خوش آمد گويي هم مياد ولي وقتي متني رو ارسال ميكنم از كلاينت هيچي تو سرور دريافت نميشه كه براي كلاينت ها بياد

saman6384
جمعه 27 خرداد 1390, 10:55 صبح
عزیزم گفتم بهت که!
مشکله برنامت اینه که می خوای همه receive هارو بریزی تو یه ترد!!!

به نظر من بیا از asynchronous سوکت استفاده کن! هم کار باهاش راحته! هم خودش ترد جدا میسازه واست!!

msdn خیلی قشنگ با مثال توضیح داده ، بخونش اگه جاییشو متوجه نشدی بپرس تا کمکت کنم

Using an Asynchronous Server Socket
(http://msdn.microsoft.com/en-us/library/5w7b7x5f.aspx)
Using an Asynchronous Client Socket (http://msdn.microsoft.com/en-us/library/bbx2eya8.aspx)

البته باز بگم! میتوونی از روش خودت استفاده کنی! اما به شرطی که به جای for از 10 تا ترد استفاده کنی!!

amatur_barnamenevis
جمعه 27 خرداد 1390, 11:03 صبح
ممنون سامان جان .ببينم چي كار ميتونم بكنم شرمنده يكم زيادي گير دادم اين دوتا لينك رو ميخونم ببينم چي ميشه بازم ممنون .بعدا مزاحمت ميشم

amatur_barnamenevis
پنج شنبه 16 تیر 1390, 14:29 عصر
من كدم رو به اين حالت تغيير دادم الان چند كلاينت ميتونن متصل بشن ولي فقط آخرين كلاينت ميتونه ارسال و دريافت داشته باشه اگه بتونم زمانيكه سرور منتظر recieve هست پورت كلاينت فرستنده رو مشخص كنم اونوقت ميتونم حلش كنم ولي فقط يه چيز مونده موقعي كه تو حالت Recieve هستش وقتي دريافت ميكنه ميخوام پورتش رو چك كنم ولي نميدونم چطوري؟؟؟

private void listening()
{
while (true)
{
try
{
for (i = 1; i <=5; i++)
{
newclient[--i] = connection.Accept();
//Daryafte etelaate Client Va Namayeshe AAn
client[i] = (IPEndPoint)newclient[i].RemoteEndPoint;
clients[i] = client[i].Port;
//Tedade Client haye Motasel Shode ra Barmigardanad
count = 0;
for (int counter = 0; counter < clients.Length; counter++)
{
if (clients[counter] != 0)
count++;
}

//Namayeshe Etelaate Client Motasel Shode
fillTextBox(client[i].Port.ToString() + " is Connected.");
//Ersale Peyghame Welcome Be client
newclient[i].Send(msgserver);
//Raftan be Halate Daryafte DADEHA
nakh2 = new Thread(new ThreadStart(daterecieve));
nakh2.Start();
}
}
catch (Exception h)
{
fillTextBox("Error in Serving() Listening. " + h.Message);
}
}
}
private void daterecieve()
{
while (true)
{
length = newclient[i].Receive(data);
if (length > 0)
{
textfromclient = System.Text.Encoding.UTF8.GetString(data, 0, length);
if (textfromclient == "serverbye")
{
fillTextBox(client[i].Address.ToString() + " Disconnect!");
}
else
{
String[] spliting = textfromclient.Split(':');
text = spliting[1];
fillTextBox(client[i].Address.ToString() + " Say:" + text);
textforsend = Encoding.ASCII.GetBytes(textfromclient);
for (j=0;j<count;j++)
newclient[j].Send(textforsend);
}
}
}
}
اون clients رو كه ميبيني گذاشتم تا پورت هاي اتصالي رو توي يه آرايه قرار بده .

saman6384
شنبه 18 تیر 1390, 20:18 عصر
خوب عزیز
من که بهت گفتم!
یا باید خودت دستی واسه هر کدوم از کلاینهتا یه ترد درست کنی!
یا از روشی که تو پست قبل گفتم استفاده کنی که خودش ترد میسازه!