質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Q&A

解決済

2回答

785閲覧

Ruby socketの受け取る時間 タイムアウト処理

kazuyakazuya

総合スコア193

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

0グッド

2クリップ

投稿2019/08/18 06:35

編集2019/08/18 11:57

前回の質問
結局だめだったので、breakで処理を終わらせようと思います。

以下のコード
1 クライアントがipconfigを実行しサーバーへ実行結果を投げる。
2 サーバーが実行結果を受け取り表示。(今回ここでつまづいている)
3 次はサーバーからクライアントへ文字列(コマンド)を発行
4 クラナントが受け取った文字列(コマンド)を実行して結果をサーバーへ投げる
5 サーバーが結果を受け取り表示

client

1#! ruby -Ku 2require "kconv" 3require 'socket' 4#ipconfigを実行し結果を投げる 5sock = TCPSocket.open("localhost","55555") 6sock.write(`ipconfig`) 7 8#受け取ったコマンドを実行する。 9while cmd = sock.gets 10 sock.write(`#{cmd}`) 11 12end 13sock.close 14

server

1#! ruby -Ku 2require "kconv" 3require 'socket' 4require 'time' 5 6gate = TCPServer.open("55555") 7sock = gate.accept 8gate.close 9 10 11while cmd = sock.gets 12 puts(Kconv.tosjis(cmd))#ipconfig実行結果を表示! 13end 14while msg = STDIN.gets#ipconfigを表示したら、次はここで文字入力をさせたいけどできない。 15 16 sock.write(msg) 17 while cmd = sock.gets 18 puts cmd 19 end 20end 21sock.close 22

起こっていること
実行すると
クライアント側のipconfig実行結果がサーバー側へ表示されるが
その後入力不能になる。(ipconfig実行結果を受け取ったら、クライアントへコマンドを投げるため文字を入力できるようにしているのだが・・・)

server

1イーサネット アダプター VMware Network Adapter VMnet8: 2 3 接続固有の DNS サフィックス . . . . .: 4 リンクローカル IPv6 アドレス. . . . .: fe80::9176:d909:4417:e6e0%4 5 IPv4 アドレス . . . . . . . . . . . .: 192.168.75.1 6 サブネット マスク . . . . . . . . . .: 255.255.255.0 7 デフォルト ゲートウェイ . . . . . . .: 8 9Wireless LAN adapter Wi-Fi: 10 11 接続固有の DNS サフィックス . . . . .: tcn-catv.ne.jp 12 リンクローカル IPv6 アドレス. . . . .: fe80::3908:b55c:8d55:59f2%18 13 IPv4 アドレス . . . . . . . . . . . .: 192.168.11.9 14 サブネット マスク . . . . . . . . . .: 255.255.255.0 15 デフォルト ゲートウェイ . . . . . . .: 192.168.11.1 16 17イーサネット アダプター Bluetooth ネットワーク接続: 18 19 メディアの状態. . . . . . . . . . . .: メディアは接続されていません 20 接続固有の DNS サフィックス . . . . .: 21(入力したいけどできない)

この解決策として

server

1#! ruby -Ku 2require "kconv" 3require 'socket' 4require 'time' 5 6gate = TCPServer.open("55555") 7sock = gate.accept 8gate.close 9 10 11while cmd = sock.gets 12 puts(Kconv.tosjis(cmd))#ipconfig実行結果を表示! 13break←ここ! 14end 15while msg = STDIN.gets#ipconfigを表示したら、次はここで文字入力をさせたいけどできない。 16 17 sock.write(msg) 18 while cmd = sock.gets 19 puts cmd 20 end 21end 22sock.close

breakを実行させることで処理を次に進ませることができました。

ただ、breakを呼び出すタイミングが本当に難しく困っています。

自分はサーバーから文字列が5秒間送られてこなくなったらbreakを発動させようとしたのですが
意外と難しくてわかりません。

失敗コード

ruby

1#! ruby -Ku 2require "kconv" 3require 'socket' 4require 'time' 5 6gate = TCPServer.open("55555") 7sock = gate.accept 8gate.close 9 10start_time = Time.now 11while cmd = sock.gets 12 now_time = Time.now 13 s_time = now_time - start_time 14 break if s_time > 5 15 puts(Kconv.tosjis(cmd)) 16end 17while msg = STDIN.gets 18 sock.write(msg) 19 while cmd = sock.gets 20 puts cmd 21 end 22end 23sock.close 24

分からないので参考になるリンクまたは説明をお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ipconfigの結果を送った後に、接続を切らないと言うことですね。

普通は「これでおわり」という目印のデータを送ります。

サーバークライアント
待ち受け
接続
接続受け
ipconfig結果送付; 目印送付
結果を表示しつつ目印検知で結果送付終了判断
コマンド送付
コマンド受け
コマンド実行結果送付; 目印送付
結果を表示しつつ目印検知で結果送付終了判断
コマンド送付に戻るコマンド受けに戻る

投稿2019/08/18 13:03

otn

総合スコア84423

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kazuyakazuya

2019/08/18 13:05

ありがとうございます!
guest

0

自己解決

こちらにて解決しました。
https://teratail.com/questions/206661

投稿2019/08/18 12:49

kazuyakazuya

総合スコア193

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問