问题提出
某个项目中,需要获取本地ip地址,和起一个程序监听某个端口,需要获取可用的端口。网上也有一些代码,这里是修改过后的判定可用的。
代码
#include <WinSock2.h>
#include <string>
#pragma comment(lib, "Ws2_32")
using namespace std;
bool isReleasePort(unsigned short usPort)
{
WSADATA wsData;
::WSAStartup(MAKEWORD(2, 2), &wsData);//起socket环境,版本号,也有 (1,1)
SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(usPort);
addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
int ret = ::bind(s, (LPSOCKADDR)&addr, sizeof(addr));
if (ret != 0)
{
closesocket(s);
::WSACleanup();
return false;
}
closesocket(s);
::WSACleanup();
return true;
}
bool getReleasePort(short& port)
{
short num = 0;
while (!isReleasePort(port) && num<30)
{
++port;
++num;
}
if (num >= 30)
{
port = -1;
return false;
}
return true;
}
bool getHostIP(string &hip)
{
WSADATA wsData;
::WSAStartup(MAKEWORD(2, 2), &wsData);
u_long ip;
char hostname[128];
int ret = gethostname(hostname, sizeof(hostname));
if (ret == -1)
{
std::cout << "here1" << std::endl;
return false;
}
struct hostent* hent;
hent = gethostbyname(hostname);
if (NULL == hent)
{
std::cout << "here2" << std::endl;
return false;
}
//一堆地址中获取最后一个才是正确的(这个没探究过原因,不过目前测试了几台机器是可用的)
for (size_t ii = 0; hent->h_addr_list[ii] && ii < 15; ++ii)
{
ip = ((struct in_addr*)hent->h_addr_list[ii])->s_addr;
in_addr inaddr;
inaddr.s_addr = ip;
hip = inet_ntoa(inaddr);
}
if (hip.empty())
{
std::cout << "here3" << std::endl;
return false;
}
::WSACleanup();
return true;
}
int main(int argc, char** argv)
{
string ip("");
if(getHostIP(ip))
{
//成功
}
short port = 9060;
if(getReleasePort(port)) //在port的基础上获取一个可用的port
{
//成功
}
return 0;
}
以上