当前位置:网站首页>去除防火墙和虚拟机对live555启动IP地址的影响
去除防火墙和虚拟机对live555启动IP地址的影响
2022-06-23 04:38:00 【qianbo_insist】
live555 启动IP获取方式
live555 的ip获取方式和其他软件都不太一样,主要是在于他是用组播方式获取的。代码如下所示:
Boolean loopbackWorks = 1;
netAddressBits ourIPAddress(UsageEnvironment& env) {
static netAddressBits ourAddress = 0;
int sock = -1;
struct in_addr testAddr;
if (ReceivingInterfaceAddr != INADDR_ANY) {
// Hack: If we were told to receive on a specific interface address, then
// define this to be our ip address:
ourAddress = ReceivingInterfaceAddr;
}
if (ourAddress == 0) {
// We need to find our source address
struct sockaddr_in fromAddr;
fromAddr.sin_addr.s_addr = 0;
// Get our address by sending a (0-TTL) multicast packet,
// receiving it, and looking at the source address used.
// (This is kinda bogus, but it provides the best guarantee
// that other nodes will think our address is the same as we do.)
do {
loopbackWorks = 0; // until we learn otherwise
testAddr.s_addr = our_inet_addr("228.67.43.91"); // arbitrary
Port testPort(15947); // ditto
sock = setupDatagramSocket(env, testPort);
if (sock < 0) break;
if (!socketJoinGroup(env, sock, testAddr.s_addr)) break;
unsigned char testString[] = "hostIdTest";
unsigned testStringLength = sizeof testString;
if (!writeSocket(env, sock, testAddr, testPort.num(), 0,
testString, testStringLength)) break;
// Block until the socket is readable (with a 5-second timeout):
fd_set rd_set;
FD_ZERO(&rd_set);
FD_SET((unsigned)sock, &rd_set);
const unsigned numFds = sock+1;
struct timeval timeout;
timeout.tv_sec = 5;
timeout.tv_usec = 0;
int result = select(numFds, &rd_set, NULL, NULL, &timeout);
if (result <= 0) break;
unsigned char readBuffer[20];
int bytesRead = readSocket(env, sock,
readBuffer, sizeof readBuffer,
fromAddr);
if (bytesRead != (int)testStringLength
|| strncmp((char*)readBuffer, (char*)testString, testStringLength) != 0) {
break;
}
// We use this packet's source address, if it's good:
loopbackWorks = !badAddressForUs(fromAddr.sin_addr.s_addr);
} while (0);
if (sock >= 0) {
socketLeaveGroup(env, sock, testAddr.s_addr);
closeSocket(sock);
}
if (!loopbackWorks) do {
// We couldn't find our address using multicast loopback,
// so try instead to look it up directly - by first getting our host name, and then resolving this host name
char hostname[100];
hostname[0] = '\0';
int result = gethostname(hostname, sizeof hostname);
if (result != 0 || hostname[0] == '\0') {
env.setResultErrMsg("initial gethostname() failed");
break;
}
// Try to resolve "hostname" to an IP address:
NetAddressList addresses(hostname);
NetAddressList::Iterator iter(addresses);
NetAddress const* address;
// Take the first address that's not bad:
netAddressBits addr = 0;
while ((address = iter.nextAddress()) != NULL) {
netAddressBits a = *(netAddressBits*)(address->data());
if (!badAddressForUs(a)) {
addr = a;
break;
}
}
// Assign the address that we found to "fromAddr" (as if the 'loopback' method had worked), to simplify the code below:
fromAddr.sin_addr.s_addr = addr;
} while (0);
// Make sure we have a good address:
netAddressBits from = fromAddr.sin_addr.s_addr;
if (badAddressForUs(from)) {
char tmp[100];
sprintf(tmp, "This computer has an invalid IP address: %s", AddressString(from).val());
env.setResultMsg(tmp);
from = 0;
}
ourAddress = from;
// Use our newly-discovered IP address, and the current time,
// to initialize the random number generator's seed:
struct timeval timeNow;
gettimeofday(&timeNow, NULL);
unsigned seed = ourAddress^timeNow.tv_sec^timeNow.tv_usec;
our_srandom(seed);
}
return ourAddress;
}
两个问题
1、这代码本身问题不大,一是防火墙问题,如果防火墙不能放行某些端口,是获取不到IP的,这导致直接最后的IP地址是初始值"0.0.0.0",还有一个问题,就是虚拟机引起的多IP地址地址问题。
2、当我们安装虚拟机时,会多出很多IP地址,这样导致一个问题,就是他会取到一个无用的IP地址,需要解决这两个问题。
直接修改live555 的获取IP的地方,增加配置文件是最合适的。我们自己来写一个读取文件的config文件的东西
#pragma once
#include <io.h>
#include <stdio.h>
#include <stdlib.h>
#include <fstream>
#include <iostream>
#include <string>
#include <algorithm> //transform
#include <map>
#pragma comment(lib,"ws2_32")
#define GET_lower(x) transform(x.begin(), x.end(), x.begin(), ::tolower)
//to translate the string to upper
#define Get_upper(x) transform(s.begin(), s.end(), s.begin(), ::toupper)
static void trim(std::string &s)
{
if (s.empty())
return;
s.erase(s.find_last_not_of('\r') + 1); //the linux system getline must remove the '\r'
s.erase(s.find_last_not_of(' ') + 1);
//s.erase(s.find_last_not_of('\t') + 1);
s.erase(0, s.find_first_not_of(' '));
//s.erase(0, s.find_first_not_of('\t'));
}
static bool ifnote(const std::string & tmp)
{
if (tmp.empty())
return false;
int l = (int)tmp.length();
char a = tmp[0];
char b;
if (l >= 2)
b = tmp[1];
if (l == 1)
return a == '#';
if (l >= 2)
return a == '#' || (a == '/'&& b == '/');
return false;
}
//judge is node
//[] is the node,
//len the line's length
//if tmp is a node, the variable node return the real node name
//the tmp string has been trimed trim
static bool ifnode(const std::string & tmp, std::string &node)
{
int len = -1;
node.clear();
if (tmp.empty())
return false;
//trim(tmp);
int l = (int)tmp.size();
if (l > 2)//bigger than []
{
//cout<<"string:"<<tmp<<" "<<l<<endl;
int take = 2;
char a = tmp[0];
char b = tmp[l - 1];
if (b == '\r') //compatible with linux linux getline with '\r',but we have removed by trim function
{
b = tmp[l - 2];
take = 3;// dec the '\r'
}
if (a == '[' && b == ']')
{
len = l - take;
node = tmp.substr(1, len);
return true;
}
}
return false;
}
//static int get_key_value(std::string nodename, std::string & key, std::string & value)
//{
//
// GET_lower(nodename);
// GET_lower(key);
// //GET_lower(value);
// return splitnv(nodename, key, value);
//
//
//}
//ini file key = value , analyse out key and value
static int splitnv(const std::string& source, std::string& key, std::string& value)
{
if (source.empty())
return -1;
int pos = 0;
int len = (int)source.length();
//printf("the len is %d\n", len);
for (pos = 0; pos < len; pos++)
{
if (source[pos] == '=')
break;
}
if (pos == len - 1)
return -1;
//printf("the pos is %d\n", pos);
key = source.substr(0, pos);
value = source.substr(pos + 1);
trim(key);
trim(value);
return 0;
}
static bool load_conf_file(const char *filename, std::string node_in, std::map<std::string, std::string> &ret)
{
//std::ifstream myfile("./config.txt");
if ((_access(filename, 0)) == -1)
{
printf_s("File not exists.\n");
return false;
}
if (filename == NULL)
filename = "config.txt";
std::ifstream myfile(filename);
std::string temp, node, nodename;
if (!myfile.is_open())
{
std::cout << "can not open config.txt" << std::endl;
return false;
}
std::cout << "load config file-->" << filename << std::endl;
while (getline(myfile, temp))
{
trim(temp);
if (!ifnote(temp)) //if is the node
{
std::string key, value;
bool isnode = ifnode(temp, node);
if (isnode)
nodename = node;//
else
{
if (node_in.compare(nodename) == 0)
{
if (splitnv(temp, key, value) == 0)
ret[key] = value;
}
}
}
}
myfile.close();
return 0;
}
配置文件
配置文件写成节点的形式
[ipport]
ip=192.168.1.11
port= 8080
#include "node_config.h"
netAddressBits ourIPAddress()
{
std::map<std::string, std::string> ret;
if(load_conf_file("config2.txt", "ipport", ret) == true)
{
std::cout << "ret size is " << ret.size() << std::endl;
std::cout << ret["ip"] << std::endl;
std::cout << ret["port"] << std::endl;
return inet_addr(ret["ip"].c_str());
}
.....以下使用原live555的代码
}
int main()
{
std::cout<<ourIPAddress()<<std::endl;
}
这样就可以直接读出来了,也就是当我们的配置文件不存在时,使用原始代码获取,配置文件存在时,使用配置文件的IP地址。从而解决了防火墙和虚拟机这些个问题。
边栏推荐
- Explicability of counter attack based on optimal transmission theory
- Work accumulation - judge whether GPS is on
- ant使用总结(二):相关命令说明
- Leetcode topic analysis: factorial training zeroes
- Tcp/ip explanation (version 2) notes / 3 link layer / 3.4 bridge and switch
- Ant Usage Summary (III): batch packaging apk
- 三项最高级认证,两项创新技术、两大优秀案例,阿里云亮相云原生产业大会
- True MySQL interview question (24) -- row column exchange
- 微软面试题:打印折纸的折痕
- 十一、纺织面料下架功能的实现
猜你喜欢

微软面试题:打印折纸的折痕

Real MySQL interview questions (25) -- common group comparison scenarios

jvm-06. Garbage collector

最优传输理论下对抗攻击可解释性

Real MySQL interview question (23) -- pinduoduo ball game analysis

New classes are launched | 5 minutes each time, you can easily play with Alibaba cloud container service!

Kotlin Android simple activity jump, simple combination of handler and thread

如何指定pig-register项目日志的输出路径

Cloud native database is the future

【Cocos2d-x】可擦除的Layer:ErasableLayer
随机推荐
mysql读已提交和可重复度区别
【Leetcode】431. Encode N-ary Tree to Binary Tree(困难)
Leetcode topic analysis: factorial training zeroes
mongodb项目中可能出现的坑
PAT 乙等 1023 组个最小数
Pat class B 1016 C language
金融科技之高效办公(一):自动生成信托计划说明书
The difference between SaaS software and traditional software delivery mode
Summary of ant usage (I): using ant to automatically package apk
PAT 乙等 1016 C语言
SQL statement error caused by the same SQL table name and function name.
Tcp/ip explanation (version 2) notes / 3 link layer / 3.4 bridge and switch
PAT 乙等 1013 C语言
Cryptography series: certificate format representation of PKI X.509
Activity startup mode and life cycle measurement results
[cocos2d-x] screenshot sharing function
PAT 乙等 1009 C语言
【Vivado那些事儿】XilinxCEDStore介绍
PAT 乙等 1010 C语言
如何为 Arduino IDE 安装添加库