怎样实现网络发现【100分】

aimeast 2008-12-22 11:04:59
先说一个例子:
星际里面的网络对战(1.15版),不管是选择ipx协议还是udp协议。只要在一个局域网里面,有一个人建好一个地图之后,其他的人都可以看到这个,也可以加入这个地图。而且是不需要配置服务器,也不需要对方ip的。不管在什么样的局域网里都可以用。

我的问题是怎样才能用程序实现这样的功能。

就是在一个局域网里,用某种机制,或者是用某种协议,来实现这种自动寻找到对方的功能。

如果你要说某种机制,只要说说原理就可以了。
...全文
379 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
jy251 2008-12-25
  • 打赏
  • 举报
回复
8楼绝对精辟
wartim 2008-12-24
  • 打赏
  • 举报
回复
除了用上面我说的广播外,还可以用webservice,而且是保存信息的

客户端


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

namespace WindowsApplication39
{
public partial class Form1 : Form
{
delegate void General();
RegisterWebService.Service RWS = new WindowsApplication39.RegisterWebService.Service();

public Form1()
{
InitializeComponent();
listBox1.Items.Add("名称 连接者 时间");
button1.Text = "新广播";
this.Size = new Size(432, 305);
RWS.Timeout = 8000;
RWS.CookieContainer = new CookieContainer();
Thread ListenThread = new Thread(new ThreadStart(Listen));
ListenThread.IsBackground = true;
ListenThread.Start();
}

void Listen()
{
General G;
int Start = Environment.TickCount;
while (true)
try
{
int End = Environment.TickCount;
if (End - Start < 5000)
continue;
listBox1.Invoke(G = delegate()
{
listBox1.BeginUpdate();
listBox1.Items.Clear();
listBox1.Items.Add("名称 连接者 时间");
foreach (String S in RWS.GetRegisteredLinks())
listBox1.Items.Add(S); ;
listBox1.EndUpdate();
});
Start = Environment.TickCount;
}
catch (Exception e)
{
this.Invoke(G = delegate()
{
this.Text = e.Message;
});
}
}

void button1_Click(object sender, EventArgs e)
{
String Info = "名称 " + Dns.GetHostByName(Dns.GetHostName()).AddressList[0] + " Handle:" + this.Handle.ToString()
+ " " + DateTime.Now.ToString();
RWS.RegisterLink(Info).ToString();
}
}
}


webservice端 Service.asmx
using System;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Collections.Generic;

[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class Service : System.Web.Services.WebService
{

public Service()
{

//如果使用设计的组件,请取消注释以下行
//InitializeComponent();
}

[WebMethod]
public int RegisterLink(String Info)
{
if (Application["Infos"] == null)
Application["Infos"] = new List<String>();
((List<String>)Application["Infos"]).Add(Info);
return ((List<String>)Application["Infos"]).Count;
}

[WebMethod]
public String[] GetRegisteredLinks()
{
return ((List<String>)Application["Infos"]).ToArray();
}
}
aimeast 2008-12-24
  • 打赏
  • 举报
回复
认真学习了!
lwz1983 2008-12-24
  • 打赏
  • 举报
回复
它是监听udp端口来实现的 并不是你想象中那样
michaelnami 2008-12-24
  • 打赏
  • 举报
回复
初始化之后发送广播信号,在局域网内的机器会回送一个回应,对回应确认即可。大概思路如上
aimeast 2008-12-23
  • 打赏
  • 举报
回复
前面提到的搜索整个局域网的方法也考虑果,这样可能不会又效率。

8楼的方法可以试试。

现在感觉就是个局域网广播的过程。
wartim 2008-12-23
  • 打赏
  • 举报
回复
就是局域网广播,
可以编译完同时运行几个看看

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

namespace WindowsApplication39
{
public partial class Form1 : Form
{
delegate void SetInfo();

public Form1()
{
InitializeComponent();

button1.Text = "new game";
listBox1.Items.Add("gamename creator createtime mancount");
Thread ListenThread = new Thread(new ThreadStart(Listen));
ListenThread.IsBackground = true;
ListenThread.Start();
}

void Listen()
{
while (true)
{
Socket S = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
S.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
IPEndPoint IPEP = new IPEndPoint(IPAddress.Any, 7890);
S.Bind(IPEP);
EndPoint EP = (EndPoint)IPEP;
Byte[] Bytes = new byte[1024];
int Count = S.ReceiveFrom(Bytes, ref EP);
string stringData = Encoding.Default.GetString(Bytes, 0, Count);
Bytes = new byte[1024];
Count = S.ReceiveFrom(Bytes, ref EP);
SetInfo SI;
listBox1.Invoke(SI = delegate() { listBox1.Items.Add(Encoding.ASCII.GetString(Bytes, 0, Count)); });
S.Close();
}
}

private void button1_Click(object sender, EventArgs e)
{
String Info = "111 " + Dns.GetHostByName(Dns.GetHostName()).AddressList[0] + " " + DateTime.Now.ToString() + " 1/1";
Byte[] Bytes = new Byte[1024];
Socket S = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
IPEndPoint IPEP = new IPEndPoint(IPAddress.Broadcast, 7890);
IPEndPoint IPEP2 = new IPEndPoint(IPAddress.Parse("192.168.1.255"), 7890);
String hostname = Dns.GetHostName();
Bytes = Encoding.Default.GetBytes(Info);
S.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1);
S.SendTo(Bytes, IPEP);
S.SendTo(Bytes, IPEP2);
S.Close();
}
}
}
lmm6693065 2008-12-23
  • 打赏
  • 举报
回复
是程序自动本身自动去检测的
我就比方说我刚最近有做过跟硬件有关的东西,是网络设备考勤机,我们都是通过这边程序去网内检测,有的话直接发送请求,设备会自动响应这个请求并回发数据包过来。其实原理是一样的
sxmonsy 2008-12-23
  • 打赏
  • 举报
回复
就如楼主所说的,主机在创建游戏的同时也是创建了一个线程,并由此线程接收和发送特定的信息,这些信息通过IPX或UDP协议传输.
kingcsx666 2008-12-23
  • 打赏
  • 举报
回复
我看都是本机自己搜索的
heyu1000 2008-12-23
  • 打赏
  • 举报
回复
恩,这个问题是比较有趣,关注一下
从来没有考虑过这个问题,帮顶
GTX280 2008-12-23
  • 打赏
  • 举报
回复
补充一点,主机在创建游戏时应该开启一个线程负责接收和应答这种echo信号,本地则会开启一个线程不断发送这个echo信号,以达到
动态刷新游戏列表的目的
GTX280 2008-12-23
  • 打赏
  • 举报
回复
我感觉是这样的:先获取局域网内所有机器,然后对每个机器发送特定的讯号,还以星际为例,如果有建好的的主机则会对这个讯号作出响应,
比如返回地图信息、创建者名字、人数等等,如果没有创建主机则不会应答
本地接收这个应答然后显示在局域网游戏列表中
xdf_hubei 2008-12-23
  • 打赏
  • 举报
回复
懒散的办法:运行程序的机器定期发送广播(如2秒)
不懒散的解决办法:运行的程序监听一个UDP端口,一旦这个端口接收到消息,就广播反馈消息,那个给他发送消息的进程也去监听这个,能收到反馈,自然就找到那个机器了...
空心兜兜 2008-12-22
  • 打赏
  • 举报
回复
UP

111,131

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Creator Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧