PDA

View Full Version : سوال: کانکت شدن به لیست ip



s_s_h70
سه شنبه 13 اسفند 1392, 08:19 صبح
با سلام خدمت اساتید #C من دارم یه برنامه چت تحت شبکه مینویسم که از دوقسمت کلاینت و سرور تشکیل شده تقریباً مثل نمونه هایی که تو سایت ها و کتابهای آموزشی وجود داره ، با این تفاوت که قسمت کلاینت به جای اتصال به یک ip از چند ip استفاده میکنه ، که در نهایت به یکیشون وصل میشه.
توضیح واضح تر :
ببینید قسمت سرور که سورسش ساده و مشخصه و باید قیل از کلاینت باز و اجرا بشه که کلاینت بهش متصل بشه. اما قسمت کلاینت میخوام لیستی از ipها قرار بدم مثلاً 10 ip که به ترتیب چک کنه و به هر کدوم که تونست وصل بشه (این 10 ip فعال هستن ولی فقط یکشون برنامه سرور هست) حالا من واسه اینکه کارم رو کوچیک انجام بدم و تست کنم اومدم 2تا ip معرفی کردم و گفتم بعد از 2 ثانیه اگه نتونست به ip اولی وصل بشه به ip دومی وصل بشه ولی جواب نداد!
ممنون میشم اگه اینو رفع اشکال کنید.
این برنامه سمت کلاینت :
using System;
using System.Threading;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Windows.Forms;
using System.Timers;
namespace ConsoleApplication6
{
class Program
{
private static System.Timers.Timer aTimer;
static string input, stringdata;
static byte[] data = new byte[1024];
static int recv;
static Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
static IPEndPoint ipep = new IPEndPoint(IPAddress.Parse("192.168.1.3"), 1500);
static Thread threcive = new Thread(recive);
static Thread thconnect = new Thread(connect);
static bool conect = false;
//################################################## ##########################
static void recive()
{
try
{
Console.WriteLine("try");
while (true)
{

byte[] data = new byte[1024];
recv = server.Receive(data);
if (recv == 0)
break;
stringdata = Encoding.ASCII.GetString(data, 0, recv);
Console.WriteLine(stringdata);
}
}
catch
{
Console.WriteLine("error recive");
}
}
//################################################## ##########################
static void OnTimedEvent(object source, ElapsedEventArgs e)
{
Console.WriteLine("time clock shode");
if (conect == false)
{
thconnect.Abort();
ipep = new IPEndPoint(IPAddress.Parse("192.168.1.2"), 1500);
thconnect = new Thread(connect);
thconnect.Start();
Console.WriteLine("thconnect ejra shod");
aTimer.Enabled = false;
}
}
//################################################## ##########################
static void connect()
{
Console.WriteLine("connect vared shod");
try
{
Console.WriteLine("try connection ....");
server.Connect(ipep);
}
catch (SocketException e)
{
Console.WriteLine("error connect");
}
conect = true;
Console.WriteLine("connect ok shod");
threcive.Start();
thconnect.Abort();
}
//################################################## ##########################
static void Main()
{
aTimer = new System.Timers.Timer();
aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
aTimer.Interval = 2000;
aTimer.Enabled = true;
thconnect.Start();
Console.WriteLine("main thconnect started");
while (true)
{
input = Console.ReadLine();
if (input == "exit")
break;
data = new byte[1024];
data = Encoding.ASCII.GetBytes(input);
server.Send(data,data .Length ,SocketFlags.None);
}
Console.WriteLine("Disconnect from server...");
server.Shutdown(SocketShutdown.Both);
server.Close();
}
}
}

اینم برنامه سمت سرور :
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;
namespace server
{

public partial class Form1 : Form
{
int recv;
byte[] data = new byte[1024];
Socket client;
IPEndPoint clientep;
IPEndPoint ipep = new IPEndPoint(IPAddress.Parse("192.168.1.2"), 1500);
Socket newsock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

public void recive()
{

while (true)
{
data = new byte[1024];
recv = client.Receive(data);
if (recv == 0)
break;
textBox1.Text = Encoding.ASCII.GetString(data, 0, recv);
}
textBox1.Text = "Disconnect from " + clientep.Address;
client.Close();
newsock.Close();
}

public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
newsock.Bind(ipep);
newsock.Listen(10);
textBox1.Text = "Waiting for connect to client ...";
client = newsock.Accept();
clientep = (IPEndPoint)client.RemoteEndPoint;
textBox1.Text = "Connect with: " + clientep.Address + " at port: " + clientep.Port;
string welcome = "Welcome to my server";
data = Encoding.ASCII.GetBytes(welcome);
client.Send(data, data.Length, SocketFlags.None);
Thread th = new Thread(recive);
th.Start();
CheckForIllegalCrossThreadCalls = false;

}

private void Form1_Load(object sender, EventArgs e)
{

}

private void button2_Click(object sender, EventArgs e)
{
data = Encoding.ASCII.GetBytes(textBox1.Text);
client.Send(data, data.Length, SocketFlags.None);
}

}
}

این دو برنامه (دانلود (http://up.ashiyane.org/images/wp06yy4kbhpvm0pwr8qa.rar)) به صورت معمولی فقط با 1 ip تعریف شده درست اجرا میشه و مشکلی نداره اما بیش از 1 ip سمت کلاینت جواب نمیده.:متفکر:

s_s_h70
سه شنبه 13 اسفند 1392, 09:01 صبح
الآن یه چیز جدید فهمیدم ؛ اگه به جای 2 ثانیه 20 الی 21 ثانیه تایم بدم برنامه جواب میده.
ولی 20 ثانیه تایم زیادیه من میخوام تو 2 ثانیه جواب بده.:ناراحت:

hamid_hr
سه شنبه 13 اسفند 1392, 09:08 صبح
من نفهمیدم چرا از این روش استفاده میکنی
اگه منظورت اینه که سرور شناسایی بشه راههای بهتری هم هست؟

s_s_h70
سه شنبه 13 اسفند 1392, 09:18 صبح
من نفهمیدم چرا از این روش استفاده میکنی
اگه منظورت اینه که سرور شناسایی بشه راههای بهتری هم هست؟

بله میخوام اول سرور شناسایی بشه بعد خودکار بهش وصل بشه ، شما چه راهی بلدین؟

hamid_hr
سه شنبه 13 اسفند 1392, 09:27 صبح
من یه کار دیگه میکردم برا شناسایی سرور
تو سرور به دو تا پورت باز میکردم
مثلا 13100 و 13101
پورت اول برای کار با کلاینت ها بود
پورت دوم برا شناسایی کلاینت ها
توی کلاینت وقتی نرم افزار اجرا میشد به برادکست به تمام سیتمهای داخل شبکه میفرستادم به پورت 13101
بعد سیستم سرور وقتی این براد کست رو دریافت میکرد اول ای پی کلاینت رو پیدا میکرد بعد یه بسته به سمت کلاینت میفرستاد
کلاینتم ای پی سرور رو از طریق این بسته پیدا میکردو ادامه کار

s_s_h70
سه شنبه 13 اسفند 1392, 09:37 صبح
من یه کار دیگه میکردم برا شناسایی سرور
تو سرور به دو تا پورت باز میکردم
مثلا 13100 و 13101
پورت اول برای کار با کلاینت ها بود
پورت دوم برا شناسایی کلاینت ها
توی کلاینت وقتی نرم افزار اجرا میشد به برادکست به تمام سیتمهای داخل شبکه میفرستادم به پورت 13101
بعد سیستم سرور وقتی این براد کست رو دریافت میکرد اول ای پی کلاینت رو پیدا میکرد بعد یه بسته به سمت کلاینت میفرستاد
کلاینتم ای پی سرور رو از طریق این بسته پیدا میکردو ادامه کار

بله حرف شما تا حدودی درسته ولی من یه محدودیت هایی دارم :
اول اینکه برنامه سمت کلاینت نباید هیچ پورتی رو اوپن کنه فقط باید به پورت سرور وصل بشه ، در ضمن شما هم یه جا اشتباه کردین چون من ip سرور رو نیاز دارم پس سرور باید برادکست بفرسته نه کلاینت ، که باز هم برای دریافت بسته برادکست کلاینت مجبوره پورت باز کنه.
در هر صورت تا جایی که تو 2 روز کامل هر راهی به ذهنم رسید رفتم ولی هیچ کدوم مثل همین راهی که گفتم منطقی و درست نیست ولی متأسفانه سریع جواب نمیده اگه بتونین یه راه بدرد بخور معرفی کنید یا همین روش منو اصلاح کنید ممنون میشم.

hamid_hr
سه شنبه 13 اسفند 1392, 09:43 صبح
ببینین کلاینت وقتی باز شد باید براد کست بفرسته تا سرور جوابشو بده
بعدشم یه پورت به مدت چند ثانیه باز کنین پاسخ که از سرور دریافت شد پورتو ببندین:لبخند:

s_s_h70
سه شنبه 13 اسفند 1392, 09:47 صبح
دوست عزیز من که گفتم کلاینت اصلاً نباید پورت باز کنه مثلاً تو ویندوز 7 به محض باز کردن پورت اگه فایروال فعال باشه یه پنجره باز میشه واسه باز کردن پورت اجازه میگیره ، منم میخوام با همین روش تست کردن ip ها سرور رو پیدا کنم که متأسفانه به مشکل خوردم.

hamid_hr
سه شنبه 13 اسفند 1392, 10:30 صبح
خب چرا همزمان به همه ای پی ها درخواست نمیفرستی
بالاخره یکیش که سرور هست جواب میده تو کمتر از 2 ثانیه

s_s_h70
چهارشنبه 14 اسفند 1392, 07:29 صبح
با سلام خدمت اساتید #C من دارم یه برنامه چت تحت شبکه مینویسم که از دوقسمت کلاینت و سرور تشکیل شده تقریباً مثل نمونه هایی که تو سایت ها و کتابهای آموزشی وجود داره ، با این تفاوت که قسمت کلاینت به جای اتصال به یک ip از چند ip استفاده میکنه ، که در نهایت به یکیشون وصل میشه.
توضیح واضح تر :
ببینید قسمت سرور که سورسش ساده و مشخصه و باید قیل از کلاینت باز و اجرا بشه که کلاینت بهش متصل بشه. اما قسمت کلاینت میخوام لیستی از ipها قرار بدم مثلاً 10 ip که به ترتیب چک کنه و به هر کدوم که تونست وصل بشه (این 10 ip فعال هستن ولی فقط یکشون برنامه سرور هست) حالا من واسه اینکه کارم رو کوچیک انجام بدم و تست کنم اومدم 2تا ip معرفی کردم و گفتم بعد از 2 ثانیه اگه نتونست به ip اولی وصل بشه به ip دومی وصل بشه ولی جواب نداد!
ممنون میشم اگه اینو رفع اشکال کنید.
این برنامه سمت کلاینت :
using System;
using System.Threading;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Windows.Forms;
using System.Timers;
namespace ConsoleApplication6
{
class Program
{
private static System.Timers.Timer aTimer;
static string input, stringdata;
static byte[] data = new byte[1024];
static int recv;
static Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
static IPEndPoint ipep = new IPEndPoint(IPAddress.Parse("192.168.1.3"), 1500);
static Thread threcive = new Thread(recive);
static Thread thconnect = new Thread(connect);
static bool conect = false;
//################################################## ##########################
static void recive()
{
try
{
Console.WriteLine("try");
while (true)
{

byte[] data = new byte[1024];
recv = server.Receive(data);
if (recv == 0)
break;
stringdata = Encoding.ASCII.GetString(data, 0, recv);
Console.WriteLine(stringdata);
}
}
catch
{
Console.WriteLine("error recive");
}
}
//################################################## ##########################
static void OnTimedEvent(object source, ElapsedEventArgs e)
{
Console.WriteLine("time clock shode");
if (conect == false)
{
thconnect.Abort();
ipep = new IPEndPoint(IPAddress.Parse("192.168.1.2"), 1500);
thconnect = new Thread(connect);
thconnect.Start();
Console.WriteLine("thconnect ejra shod");
aTimer.Enabled = false;
}
}
//################################################## ##########################
static void connect()
{
Console.WriteLine("connect vared shod");
try
{
Console.WriteLine("try connection ....");
server.Connect(ipep);
}
catch (SocketException e)
{
Console.WriteLine("error connect");
}
conect = true;
Console.WriteLine("connect ok shod");
threcive.Start();
thconnect.Abort();
}
//################################################## ##########################
static void Main()
{
aTimer = new System.Timers.Timer();
aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
aTimer.Interval = 2000;
aTimer.Enabled = true;
thconnect.Start();
Console.WriteLine("main thconnect started");
while (true)
{
input = Console.ReadLine();
if (input == "exit")
break;
data = new byte[1024];
data = Encoding.ASCII.GetBytes(input);
server.Send(data,data .Length ,SocketFlags.None);
}
Console.WriteLine("Disconnect from server...");
server.Shutdown(SocketShutdown.Both);
server.Close();
}
}
}

اینم برنامه سمت سرور :
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;
namespace server
{

public partial class Form1 : Form
{
int recv;
byte[] data = new byte[1024];
Socket client;
IPEndPoint clientep;
IPEndPoint ipep = new IPEndPoint(IPAddress.Parse("192.168.1.2"), 1500);
Socket newsock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

public void recive()
{

while (true)
{
data = new byte[1024];
recv = client.Receive(data);
if (recv == 0)
break;
textBox1.Text = Encoding.ASCII.GetString(data, 0, recv);
}
textBox1.Text = "Disconnect from " + clientep.Address;
client.Close();
newsock.Close();
}

public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
newsock.Bind(ipep);
newsock.Listen(10);
textBox1.Text = "Waiting for connect to client ...";
client = newsock.Accept();
clientep = (IPEndPoint)client.RemoteEndPoint;
textBox1.Text = "Connect with: " + clientep.Address + " at port: " + clientep.Port;
string welcome = "Welcome to my server";
data = Encoding.ASCII.GetBytes(welcome);
client.Send(data, data.Length, SocketFlags.None);
Thread th = new Thread(recive);
th.Start();
CheckForIllegalCrossThreadCalls = false;

}

private void Form1_Load(object sender, EventArgs e)
{

}

private void button2_Click(object sender, EventArgs e)
{
data = Encoding.ASCII.GetBytes(textBox1.Text);
client.Send(data, data.Length, SocketFlags.None);
}

}
}

این دو برنامه (دانلود (http://up.ashiyane.org/images/wp06yy4kbhpvm0pwr8qa.rar)) به صورت معمولی فقط با 1 ip تعریف شده درست اجرا میشه و مشکلی نداره اما بیش از 1 ip سمت کلاینت جواب نمیده.:متفکر:

دوست عزیز من که گفتم نمیشه چون کلاینت مجبور میشه یه پورت باز کنه اما خدا رو شکر مشکلم حل شد.
تو این تابع OnTimedEvent قبل از ipep باید سوکت رو میبستم و دوباره باز میکردم.:تشویق: