Windows上のSQLサーバ(名前つきインスタンス)にLinuxのsqlcmdから接続したい。
オプションの -S に サーバ名,ポート番号 を指定すればいいのだけど、肝心の
ポート番号が外部からわからない。
ServerBrowserServiceにアクセスするとポート番号が得られるみたいだけど、
リクエストに何を送ればいいのやら?
同じことを考えるひとはいるもので、ググって
https://qiita.com/awachang/items/c4fecbace9f02d923866
を見つけた。
ふむ。UDP1434につないで、0x4インスタンス名0x0を送ればいいのか。
Perlでソケット通信するサンプルを探して、改変して作ってみた。
実行すると、帰ってこない。。。
SQLサーバ側のパケットキャプチャだと返事をしているようだけど、
Perlプログラムは何かを待っている・・・。
もしかすると、UDPだし、コネクションクローズしてくれないから
ずーっと待っているのでは?
そう思ってソケットから読み取るのを10バイトにしたら、なんか動いた。
では全体を・・・試しているSQLサーバだとサーバ名とかインスタンス名
とかで全部で95バイト。読み取るバイト数を96バイトにしたら待ちのまま。。。
うーん。サーバ名とインスタンス名は変わっても問題ないようにしたいなぁ。
参考にしたページで使われているPHPだとfreadがよきに計らってくれるらしく、
ストリームがおわったら自動クローズしてくれるみたいだ。
うーん。。。。
結局、;;がたぶんデータの最後だろう、っていうことにして連続2回;がきた
ら終了することにした。
いまいちだけど、目的は達成できたしこれでいいのだ。
#!/usr/bin/perl
use strict;
use warnings;
use Socket;
my $remote_host = $ARGV[0];
my $remote_port = 1434;
my $instance = $ARGV[1];
my $sock;
socket($sock, PF_INET, SOCK_DGRAM, getprotobyname('udp' ))
or die "Cannot create socket: $!";
my $packed_remote_host = inet_aton($remote_host)
or die "Cannot pack $remote_host: $!";
my $sock_addr = sockaddr_in($remote_port, $packed_remote_host)
or die "Cannot pack $remote_host:$remote_port: $!";
connect($sock, $sock_addr)
or die "Cannot connect $remote_host:$remote_port: $!";
my $old_handle = select $sock;
$| = 1;
select $old_handle;
print $sock pack("c",0x04) . $instance . pack("c",0x00);
shutdown $sock, 1;
my $check = 0;
my $before = "";
my $allstring = "";
while ( $check == 0 ){
read $sock, my $data, 1;
if ( "$before$data" eq ";;" ) { $check = 1; }
$before = $data ;
$allstring .= $data;
}
#print "$allstring\n";
my ( @newport ) = $allstring =~ /\;tcp\;(\d+)\;/;
print "$newport[0]\n";
close $sock;
オプションの -S に サーバ名,ポート番号 を指定すればいいのだけど、肝心の
ポート番号が外部からわからない。
ServerBrowserServiceにアクセスするとポート番号が得られるみたいだけど、
リクエストに何を送ればいいのやら?
同じことを考えるひとはいるもので、ググって
https://qiita.com/awachang/items/c4fecbace9f02d923866
を見つけた。
ふむ。UDP1434につないで、0x4インスタンス名0x0を送ればいいのか。
Perlでソケット通信するサンプルを探して、改変して作ってみた。
実行すると、帰ってこない。。。
SQLサーバ側のパケットキャプチャだと返事をしているようだけど、
Perlプログラムは何かを待っている・・・。
もしかすると、UDPだし、コネクションクローズしてくれないから
ずーっと待っているのでは?
そう思ってソケットから読み取るのを10バイトにしたら、なんか動いた。
では全体を・・・試しているSQLサーバだとサーバ名とかインスタンス名
とかで全部で95バイト。読み取るバイト数を96バイトにしたら待ちのまま。。。
うーん。サーバ名とインスタンス名は変わっても問題ないようにしたいなぁ。
参考にしたページで使われているPHPだとfreadがよきに計らってくれるらしく、
ストリームがおわったら自動クローズしてくれるみたいだ。
うーん。。。。
結局、;;がたぶんデータの最後だろう、っていうことにして連続2回;がきた
ら終了することにした。
いまいちだけど、目的は達成できたしこれでいいのだ。
#!/usr/bin/perl
use strict;
use warnings;
use Socket;
my $remote_host = $ARGV[0];
my $remote_port = 1434;
my $instance = $ARGV[1];
my $sock;
socket($sock, PF_INET, SOCK_DGRAM, getprotobyname('udp' ))
or die "Cannot create socket: $!";
my $packed_remote_host = inet_aton($remote_host)
or die "Cannot pack $remote_host: $!";
my $sock_addr = sockaddr_in($remote_port, $packed_remote_host)
or die "Cannot pack $remote_host:$remote_port: $!";
connect($sock, $sock_addr)
or die "Cannot connect $remote_host:$remote_port: $!";
my $old_handle = select $sock;
$| = 1;
select $old_handle;
print $sock pack("c",0x04) . $instance . pack("c",0x00);
shutdown $sock, 1;
my $check = 0;
my $before = "";
my $allstring = "";
while ( $check == 0 ){
read $sock, my $data, 1;
if ( "$before$data" eq ";;" ) { $check = 1; }
$before = $data ;
$allstring .= $data;
}
#print "$allstring\n";
my ( @newport ) = $allstring =~ /\;tcp\;(\d+)\;/;
print "$newport[0]\n";
close $sock;
コメント
コメントを投稿