What to do with the results of getaddrinfo? - sockets

Using getaddrinfo to query a host, I get a number of results:
struct addrinfo hints;
hints.ai_flags = 0
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = 0
hints.ai_addrlen = 0;
hints.ai_addr = NULL;
hints.ai_canonname= NULL;
hints.ai_next = NULL;
struct addrinfo *res = NULL;
getaddrinfo("google.com", "http", &hints, &res);
res gets filled in with a list of 11 possible addresses I could use to connect to google.com with the given parameters:
1 family=2, addr.port=80, addr.address=74.125.226.98, protocol=6, socktype=1, flags=0
2 family=2, addr.port=80, addr.address=74.125.226.104, protocol=6, socktype=1, flags=0
3 family=2, addr.port=80, addr.address=74.125.226.100, protocol=6, socktype=1, flags=0
4 family=2, addr.port=80, addr.address=74.125.226.99, protocol=6, socktype=1, flags=0
5 family=2, addr.port=80, addr.address=74.125.226.96, protocol=6, socktype=1, flags=0
6 family=2, addr.port=80, addr.address=74.125.226.102, protocol=6, socktype=1, flags=0
7 family=2, addr.port=80, addr.address=74.125.226.110, protocol=6, socktype=1, flags=0
8 family=2, addr.port=80, addr.address=74.125.226.97, protocol=6, socktype=1, flags=0
9 family=2, addr.port=80, addr.address=74.125.226.105, protocol=6, socktype=1, flags=0
10 family=2, addr.port=80, addr.address=74.125.226.103, protocol=6, socktype=1, flags=0
11 family=2, addr.port=80, addr.address=74.125.226.101, protocol=6, socktype=1, flags=0
My question is, which do I use? Should I just always take the first one, or pick one at random? Or should I try each one in order until connect() succeeds?

There is not an officially defined order, but unless you have a good reason not to: try them in order, skipping any that don't match your requirements (eg, wrong protocol). Usually DNS servers will round-robin or somehow permute the results. (You can probably see that if your run your test multiple times in a row or running nslookup or dig a few times on google.com.)
https://en.wikipedia.org/wiki/Round-robin_DNS

Traditionally the first entry is used.
DNS servers make use of this to balance the load between multiple servers, that is they return a different order each time. So you should pick the first one and continue from there until you get a successful connection.

You should loop through them, one at a time in order, trying to connect() to each one until either one succeeds or you exhaust the list.

Related

Perl increment operator

$a = 10;
$b = (++$a) + (++$a) + (++$a);
print $b;
I am getting the answer 37.
Can anybody explain how this operation is proceeding and how the result is getting 37.
As per my logic it should be 36:
(++$a) + (++$a) + (++$a)
11 + 12 + 13 = 36
But I am getting the answer 37
Perl's is executing this as
( ( $a = $a + 1 ) + ( $a = $a + 1 ) ) + ( $a = $a + 1 )
You have even put the ++$a in parentheses so to say that they should happen first, before the additions, although they are of higher priority anyway
This is centred around the fact that the assignment operator = returns its first operand, which allows operations like
(my $x = $y) =~ tr/A-Z/a-z/
If the result of the assignment were simply the value copied from $y to $x then the tr/// would cause a Can't modify a constant item or the equivalent, and it would have no effect on what was stored in either variable
Here is the variable $a, and the execution is as follows
Execute the first increment, returning $a
$a is now 11
Execute the second increment, returning $a again
$a is now 12
Execute the first addition, which adds what was returned by the two increments—both $a
$a is 12, so $a + $a is 24
Execute the third increment, returning $a again
$a is now 13
Execute the second addition, which adds the what was returned by the first addition (24) and the third increment ($a)
$a is 13, so 24 + $a is 37
Note that this should not be relied on. It is not documented anywhere except to say that it us undefined, and the behaviour could change with any release of Perl
As a complement to mob and Borodin's answer, you can see what's happening clearly if you think about how the operations are interacting with the stack and recognize that preinc returns the variable, not its value.
op | a's value | stack
$a | 10 | $a
++ | 11 | $a
$a | 11 | $a $a
++ | 12 | $a $a
+ | 12 | 24
$a | 12 | 24 $a
++ | 13 | 24 $a
+ | 13 | 37
As it has been noted in comments, changing a variable multiple times within a single statement leads to undefined behavior, as explained in perlop.
So the exact behavior is not specified and may vary between versions and implementations.
As to how it works out, here is one way to see it. Since + is a binary operator, at each operation its left-hand-side operand does get involved when ++ is executed on the other. So at each position $a gets ++ed, and picks up another increment as a LHS operand.
That means that the LHS $a gets incremented additionally (to its ++) once in each + operation. The + operations after the first one must accumulate these, one extra for each extra term. With three terms here that's another +3, once. So there are altogether 7 increments.
Yet another (fourth) term incurs an extra +4, etc
perl -wE'$x=10; $y = ++$x + ++$x + ++$x + ++$x; say $y' # 4*10 + 2+2+3+4
This is interesting to tweak by changing ++$x to $x++ -- the effect depends on position.
Increments in steps
first $a gets incremented (to 11)
in the first addition, as the second $a is incremented (to 11) the first one gets a bump as well being an operand (to 12)
in the second addition, the second $a gets incremented (to 12) as an operand
as the second addition comes up, the third $a is updated and thus picks up increments from both additions, plus its increment (to 13)
The enumeration of $a above refers to their presence at multiple places in the statement.
As #Håkon Hægland pointed out, running this code under B::Concise, which outputs the opcodes that the Perl script generates, is illuminating. Here's are two slightly different examples than the one you provided:
$ perl -E 'say $b=$a + ((++$a)+(++$a))'
6
$ perl -E 'say $b=($a+(++$a)) + (++$a)'
4
So what's going on here? Let's look at the opcodes:
$ perl -MO=Concise -E 'say $b=$a+((++$a)+(++$a))'
e <#> leave[1 ref] vKP/REFC ->(end)
1 <0> enter ->2
2 <;> nextstate(main 47 -e:1) v:%,{,469764096 ->3
d <#> say vK ->e
3 <0> pushmark s ->4
c <2> sassign sKS/2 ->d
a <2> add[t6] sK/2 ->b
- <1> ex-rv2sv sK/1 ->5
4 <#> gvsv[*a] s ->5
9 <2> add[t5] sKP/2 ->a
6 <1> preinc sKP/1 ->7
- <1> ex-rv2sv sKRM/1 ->6
5 <#> gvsv[*a] s ->6
8 <1> preinc sKP/1 ->9
- <1> ex-rv2sv sKRM/1 ->8
7 <#> gvsv[*a] s ->8
- <1> ex-rv2sv sKRM*/1 ->c
b <#> gvsv[*b] s ->c
-e syntax OK
There are no conditionals in this program. The left most column indicates the order of operations in this program. Whereever you see the ex-rv2sv token, that is where Perl is reading the value of an expression like a global scalar variable.
The preinc operations occur at labels 6 and 8. The add operations occur at labels 9 and a. This tells us that both increments occurred before Perl performed the additions, and so the final expression would be something like 2 + (2 + 2) = 6.
In the other example, the opcodes look like
$ perl -MO=Concise -E 'say $b=($a+(++$a)) + (++$a)'
e <#> leave[1 ref] vKP/REFC ->(end)
1 <0> enter ->2
2 <;> nextstate(main 47 -e:1) v:%,{,469764096 ->3
d <#> say vK ->e
3 <0> pushmark s ->4
c <2> sassign sKS/2 ->d
a <2> add[t6] sK/2 ->b
7 <2> add[t4] sKP/2 ->8
- <1> ex-rv2sv sK/1 ->5
4 <#> gvsv[*a] s ->5
6 <1> preinc sKP/1 ->7
- <1> ex-rv2sv sKRM/1 ->6
5 <#> gvsv[*a] s ->6
9 <1> preinc sKP/1 ->a
- <1> ex-rv2sv sKRM/1 ->9
8 <#> gvsv[*a] s ->9
- <1> ex-rv2sv sKRM*/1 ->c
b <#> gvsv[*b] s ->c
-e syntax OK
Now the preinc operations still occur at 6 and 9, but there is an add operation at label 7, after $a has only be incremented one time. This makes the values used in the final expression (1 + 1) + 2 = 4.
So in your example:
$ perl -MO=Concise -E '$a=10;$b=(++$a)+(++$a)+(++$a);say $b'
l <#> leave[1 ref] vKP/REFC ->(end)
1 <0> enter ->2
2 <;> nextstate(main 47 -e:1) v:%,{,469764096 ->3
5 <2> sassign vKS/2 ->6
3 <$> const[IV 10] s ->4
- <1> ex-rv2sv sKRM*/1 ->5
4 <#> gvsv[*a] s ->5
6 <;> nextstate(main 47 -e:1) v:%,{,469764096 ->7
g <2> sassign vKS/2 ->h
e <2> add[t7] sK/2 ->f
b <2> add[t5] sK/2 ->c
8 <1> preinc sKP/1 ->9
- <1> ex-rv2sv sKRM/1 ->8
7 <#> gvsv[*a] s ->8
a <1> preinc sKP/1 ->b
- <1> ex-rv2sv sKRM/1 ->a
9 <#> gvsv[*a] s ->a
d <1> preinc sKP/1 ->e
- <1> ex-rv2sv sKRM/1 ->d
c <#> gvsv[*a] s ->d
- <1> ex-rv2sv sKRM*/1 ->g
f <#> gvsv[*b] s ->g
h <;> nextstate(main 47 -e:1) v:%,{,469764096 ->i
k <#> say vK ->l
i <0> pushmark s ->j
- <1> ex-rv2sv sK/1 ->k
j <#> gvsv[*b] s ->k
-e syntax OK
We see preinc occurring at labels 8, a, and d. The add operations occur at b and e. That is, $a is incremented twice, then two $a's are added together. Then $a is incremented again. Then $a is added to the result. So the output is (12 + 12) + 13 = 37.

Reading a file in perl and assigning variables

I am trying to read a file into perl and assign variables to each of the characters in the file. I have done this a number of times and worked quite well. But for this file I am not quite sure what is it I am doing wrong.
So the file looks like this:
1 1 4 4 4 0.1000E+01 0.1000E+01 0.1966E+02 1 66 2 2 9 81
2 2 4 4 4 0.1000E+01 0.1000E+01 0.2832E+02 1 9 3 3 9 13
3 1 4 4 4 0.1000E+01 0.1000E+01 0.2538E+02 1 75 2 2 13 82
4 2 4 4 4 0.1000E+01 0.1000E+01 0.1507E+02 127 1 3 3 81 82
5 1 4 4 4 0.1000E+01 0.1000E+01 0.2663E+02 9 80 2 2 9 17
6 1 4 4 4 0.1000E+01 0.1000E+01 0.3031E+02 9 87 2 2 13 21
7 2 4 4 4 0.1000E+01 0.1000E+01 0.3065E+02 9 17 3 3 17 21
8 1 4 4 4 0.1000E+01 0.1000E+01 0.3574E+02 49 10 2 2 18 50
9 2 4 4 4 0.1000E+01 0.1000E+01 0.3396E+02 10 94 3 3 18 58
10 2 4 4 4 0.1000E+01 0.1000E+01 0.2903E+02 66 10 3 3 50 51
11 1 4 4 4 0.1000E+01 0.1000E+01 0.1711E+02 80 10 2 2 51 57
12 2 4 4 4 0.1000E+01 0.1000E+01 0.2776E+02 10 18 3 3 57 58
13 1 4 4 4 0.1000E+01 0.1000E+01 0.3448E+02 16 49 2 2 22 49
And here what I have been trying to do:
#!/usr/bin/perl
use strict;
open OPLINE, "<$lfile" or die "\033[31mError: Can't open $lfile\033[0m ";
my $line = <OPLINE>;
while ($line) {
#my #fields = split(" ",$line);
if ($line =~ /\s*(\d+)\s*(\d)\s*(\d)\s(\d)\s(\d)\s*(\d+)\s*(\d+)\s*(\d+)\s*(\d+)\s*(\d+)\s*(\d)\s*(\d)\s*(\d+)\s*(\d+)/){
my ($Line, $Xi, $Basis1, $Basis2, $Basis3, $Deriv1, $Deriv2, $Length, $Node1, $Node2, $der1, $der2, $Element1, $Element2) = ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14);
}
}
$line = <IPNODE>;
The script works up until the IF argument. It seems it can't match the expressions to the file format.
Any help is appreciated!
Thanks.
Have you tries something like this:
my ($discard, $Line, $Xi, $Basis1, $Basis2, $Basis3, $Deriv1,
$Deriv2, $Length, $Node1, $Node2, $der1, $der2,
$Element1, $Element2) = split(/\s+/, $line);
I've added the leading $discard variable, because the split() will treat the leading spaces as the delimiter between the first and second items.
"\d" is matching digits. You have punctuation in the decimal points, and "E" and "+": "[0-9E+.]".

Is there any difference between &$func($arg) and $func->($arg)?

While trying to understand closures, reading thru perl-faq and coderef in perlref found those examples:
sub add_function_generator {
return sub { shift() + shift() };
}
my $add_sub = add_function_generator();
my $sum = $add_sub->(4,5);
and
sub newprint {
my $x = shift;
return sub { my $y = shift; print "$x, $y!\n"; };
}
$h = newprint("Howdy");
&$h("world");
here are two forms of calling a function stored in a variable.
&$func($arg)
$func->($arg)
Are those totally equivalent (only syntactically different) or here are some differences?
There is no difference. Proof: the opcodes generated by each version:
$ perl -MO=Concise -e'my $func; $func->()'
8 <#> leave[1 ref] vKP/REFC ->(end)
1 <0> enter ->2
2 <;> nextstate(main 1 -e:1) v:{ ->3
3 <0> padsv[$func:1,2] vM/LVINTRO ->4
4 <;> nextstate(main 2 -e:1) v:{ ->5
7 <1> entersub[t2] vKS/TARG ->8
- <1> ex-list K ->7
5 <0> pushmark s ->6
- <1> ex-rv2cv K ->-
6 <0> padsv[$func:1,2] s ->7
$ perl -MO=Concise -e'my $func; &$func()'
8 <#> leave[1 ref] vKP/REFC ->(end)
1 <0> enter ->2
2 <;> nextstate(main 1 -e:1) v:{ ->3
3 <0> padsv[$func:1,2] vM/LVINTRO ->4
4 <;> nextstate(main 2 -e:1) v:{ ->5
7 <1> entersub[t2] vKS/TARG ->8
- <1> ex-list K ->7
5 <0> pushmark s ->6
- <1> ex-rv2cv sKPRMS/4 ->-
6 <0> padsv[$func:1,2] s ->7
… wait, there are actually slight differences in the flags for - <1> ex-rv2cv sKPRMS/4 ->-. Anyways, they don't seemt to matter, and both forms behave the same.
But I would recommend to use the form $func->(): I perceive this syntax as more elegant, and you can't accidentally forget to use parens (&$func works but makes the current #_ visible to the function, which is not what you'd usually want).

How to sort the matrix according to specific row?

I have a population generated by pop=[pop;x;y;z;cst,fr]; where first 4 rows are x, second 3 rows are y and third 8 rows are z. cst is sum of column 1 and fr is calculated failure rate of column 2.
6 0.876
5 0.99
3 0.939
6 0.876
4 0.837
7 0.959
4 0.953
4 0.873
0 0
5 0.95
3 0.855
4 0.873
4 0.873
5 0.95
6 0.951
66 0.00032352
6 0.876
6 0.876
6 0.965
6 0.965
4 0.953
4 0.837
4 0.953
0 0
3 0.855
6 0.951
5 0.95
0 0
0 0
3 0.855
6 0.951
59 0.00038143
6 0.965
5 0.888
6 0.965
3 0.863
7 0.889
7 0.959
4 0.953
7 0.915
6 0.968
3 0.855
3 0.855
8 0.942
4 0.873
3 0.855
8 0.942
80 0.0002327
How can I sort the specific (16,32,48) rows followed by unchanged (1:15,17:31,33:47)?
for example:
6 0.876
6 0.876
6 0.965
6 0.965
4 0.953
4 0.837
4 0.953
0 0
3 0.855
6 0.951
5 0.95
0 0
0 0
3 0.855
6 0.951
59 0.00038143
6 0.876
5 0.99
3 0.939
6 0.876
4 0.837
7 0.959
4 0.953
4 0.873
0 0
5 0.95
3 0.855
4 0.873
4 0.873
5 0.95
6 0.951
66 0.00032352
6 0.965
5 0.888
6 0.965
3 0.863
7 0.889
7 0.959
4 0.953
7 0.915
6 0.968
3 0.855
3 0.855
8 0.942
4 0.873
3 0.855
8 0.942
80 0.0002327
Please help!
It's not clear exactly what order you want, but if you know you want some specific row ordering like this: (16,32,48) rows followed by unchanged (1:15,17:31,33:47) then you can use indexing just like this:
n = [16, 32, 48, 1:15, 17:31, 33:47]; % indexes for sorting
popsort = pop(n,:); %index into pop by rows
There are various tricks you could use to create the index vector n.
Now, if you are calling a loop and appending new values to pop like this:
pop = []
for n = 1:3
% calculate x, y, z, etc.
pop=[pop;x;y;z;cst,fr];
end
Then it may be better to pre-allocate the matrix pop and put your values where you want them in the first place, or use two variables, one containing your x,y,z and the other with the cst,fr values in. That would avoid the need to sort the rows afterwards:
m = 3; % works for any number of loops
pop = zeros(m*15,2);
cst_fr = zeros(m,2);
for n = 0:m-1
% calculate x, y, z, etc.
pop(1+n*15:15+n*15,:)=[x;y;z];
cst_fr(n+1,:)=[cst,fr];
end

how to delete empty elements in the cell in a way i want

in MATLAB I have a cell array like this
a = { 1 2 2 3 4 5 [] []
2 4 5 4 3 2 4 5
4 5 4 3 4 [] [] []}
I want to remove empty elements in a way that I get this :
a = { 1 2 2 3 4 5 2 4 5 4 3 2 4 5 4 5 4 3 4}
but when I use this : a(cellfun(#isempty,a)) = [];
what I get is this :
a = {1 2 4 2 4 5 2 5 4 3 4 3 4 3 4 5 2 4 5}
which is not what I want
The problem is that the linear index runs in the direction of rows, i.e. it runs through the first conlumn, then through the second column etc.
You can see this when you call reshape on a vector:
>> reshape([1 2 3 4 5 6 7 8 9],3,3)
ans =
1 4 7
2 5 8
3 6 9
To achieve the result you want, you need to transpose a before indexing into it.
a = a';
a(cellfun(#isempty,a)) = [];
You can try this :
A(~cellfun('isempty',A))