Visual C++ 7.1C++/CLIVisual Studio .NET 2003Windows 2003.NET 1.1Windows 2000Windows XP中级开发Visual StudioWindowsC++.NET
游戏服务器扫描器






2.29/5 (7投票s)
2004 年 8 月 23 日
1分钟阅读

55014

2497
用于在局域网中查找游戏服务器的端口扫描器。
屏幕截图
引言
gfxscan 是一个简单的端口扫描器,旨在搜索局域网中运行游戏服务器的远程计算机。
它异步地向子网中的特定端口(例如反恐精英的 27015 端口)上的所有 IP 发送简单的 UDP 请求。然后解析响应以获取服务器的详细信息。可以发出许多额外的请求以了解有关游戏的更多信息,我稍后会发布这些信息。
我尝试找到一个简单的局域网端口扫描器并进行了大量 Google 搜索,但没有找到任何。因此,我决定编写自己的游戏服务器扫描器。
遇到的问题
主要问题是减少读取调用等待时间。我通过将选项 System::Net::Sockets::SocketOptionName::ReceiveTimeout
设置为 1000 来解决这个问题。
sock->SetSocketOption(System::Net::Sockets::SocketOptionLevel::Socket,
System::Net::Sockets::SocketOptionName::ReceiveTimeout,1000);
可以使用 sock->set_Blocking(false)
来取消套接字的阻塞特性。
主要代码片段
- 创建 UDP 套接字,启动一个新线程以读取来自找到服务器的主机的响应,以及向子网中的主机发送 UDP 请求
void scanServers(String* ip[],int prt,int count) { boolRead =1; port = prt; sock = new Socket(AddressFamily::InterNetwork, SocketType::Dgram,ProtocolType::Udp); readThread = new Thread(new ThreadStart(this,read)); readThread->Start(); Byte msg[]= System::Text::Encoding::ASCII->GetBytes("xxxxinfo\0"); Byte msg2[]= new Byte[1000]; msg[0] = 0xff; msg[1] = 0xff; msg[2] = 0xff; msg[3] = 0xff; for(int i=0;i<count;i++) { IPAddress* ipAdd = IPAddress::Parse(ip->GetValue(i)->ToString()); IPEndPoint* endPoint = new IPEndPoint(ipAdd,port); EndPoint* senderRemote = __try_cast<EndPoint*>(endPoint); try { sock->SendTo(msg, 0, msg->Length, SocketFlags::None, endPoint); } catch ( SocketException* se ) { //MessageBox::Show(se->Message,"exception while sending", MessageBoxButtons::OK, MessageBoxIcon::Exclamation); } } }
- 设置非阻塞和超时选项,从同一套接字读取主机数据,解码消息,然后将其发送到显示以正确显示消息
void read() { IPEndPoint* sender = new IPEndPoint(IPAddress::Any, port); EndPoint* senderRemote = __try_cast<EndPoint*>(sender); Byte msg2[]= new Byte[1000]; sock->set_Blocking(false); sock->SetSocketOption(System::Net::Sockets::SocketOptionLevel::Socket, System::Net::Sockets::SocketOptionName::ReceiveTimeout,1000); while(boolRead==1) { try { int iR = sock->ReceiveFrom(msg2, 0, msg2->Length, SocketFlags::None, &senderRemote); Char chars[] = new Char[2000]; Decoder* d = Encoding::UTF8->GetDecoder(); int charLen = d->GetChars(msg2, 0, msg2->Length, chars, 0); String* str = new String(chars); parseAndAdd(str); } catch (SocketException* se) { MessageBox::Show(se->Message,"exception while sending", MessageBoxButtons::OK, MessageBoxIcon::Exclamation); } } this->labelStatus->set_Text(new String("Scan Complete.")); this->labelStatus->Invalidate(); }
我希望创建一个类,以便提供一个整洁的接口来查找局域网中的游戏服务器,并为它们提供更多游戏信息,例如玩家数量、正在玩的游戏地图以及每个玩家的状态。
在那之前,祝您游戏愉快!