• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:TCPのプログラムで例外エラーが出て困っています)

TCPのプログラムで例外エラーが出て困っています

このQ&Aのポイント
  • java eclipseを使って通信のプログラムを作ろうとしています。
  • 参考にしている本は、TCP/IPソケットプログラミングjava編です。
  • Exception in thread "main" java.lang.IllegalArgumentException: Parameter(s): <Server> <word> [<Port>] というエラーが出ました。このエラーを調べると、「不正な引数、または不適切な引数をメソッドにわたしたことを示すためにスローされる」とかかれていました。また、 <Server> <word> [<Port>] に何か文字を入力すればよいとも書かれていました。他のページを見て試してみても、例外エラーがとれません。

質問者が選んだベストアンサー

  • ベストアンサー
  • f272
  • ベストアンサー率46% (8625/18445)
回答No.3

「不正な引数、または不適切な引数をメソッドにわたしたことを示すためにスローされる」 というのだから適切な引数をメソッドにわたさないといけないのです。 とりあえずGoogleで「eclipse 引数」で検索したら http://www.okapiproject.com/java/java_tools/eclipse/vol_2/eclipse_operation.htm#a4 こんなのが出てくる。引数ありでプログラムの実行するときの方法が書いてあるからね。 ここの例だと「サンプルプログラム」と「!」という2つの引数を渡しています。 あなたの場合だと,「サーバ名」と「サーバに渡す文字列」と「サーバのポート番号」を渡すわけだけど, 適当に3つの文字列として「127.0.0.1 telnet 80」と書けば,多分 Connected to server...sending echo string Exception in thread "main" java.net.SocketException: Connection reset というエラーが返るはず。 もう少しまともに書くなら,例えばあなたの使っているメールサーバを使わせてもらうことにして,「xxx.xxx.xxx.xxx HELO 25」と書けば(xxx.xxx.xxx.xxxはちゃんと調べて数字にしてね) Connected to server...sending echo string Received: 220 なんていう答えが返ってくるはず。

debukawa
質問者

お礼

いつも回答ありがとうございます。とても感謝しております。 127.0.0.1 telnet 80 と「プログラムの引数」の欄に入力したところ、 Exception in thread "main" java.lang.NoClassDefFoundError: TCPEchoClient Caused by: java.lang.ClassNotFoundException: TCPEchoClient at java.net.URLClassLoader$1.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(Unknown Source) at java.lang.ClassLoader.loadClass(Unknown Source) at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source) at java.lang.ClassLoader.loadClass(Unknown Source) at java.lang.ClassLoader.loadClassInternal(Unknown Source) Could not find the main class: TCPEchoClient. Program will exit. また、IPアドレス test 25 と入力して実行しても上のエラーが出ました。 何がいけないのでしょうか?

その他の回答 (7)

  • f272
  • ベストアンサー率46% (8625/18445)
回答No.8

> Received: +OK これが返ってくるということは,入力したポート番号(多分110)はメールサーバのPOPプロトコルでアクセスするポートと言う事ですね。この場合は,こちらからどんな文字列(testとかwordとか)を送っても,まず+OKが返ってきます。これはシェルのプロンプトから telnet メールサーバのアドレス ポート番号 とすることで確認できるでしょう。(これで接続したときはquitで終了する) もしポート番号を25にしてsmtpでアクセスするように変更すると,引数としては メールサーバのアドレス test 25 となって,返ってくるのは Connected to server...sending echo string Received: 220 となるでしょう。 なお // サーバから同じ文字列を受信する とプログラムのコメントに書いてありますが,これは「サーバから送った文字列と同じ文字数を受信する」の間違いでしょう。

debukawa
質問者

お礼

回答ありがとうございます。 25と入力したところ、 Connected to server...sending echo string Received: 220 となりました。ほかのポート番号を入力して何が返ってくるか試してみようと思います。 f272さんのご指導により、このプログラムを動かすことができました。 私の質問を親切に答えてくださいまして本当にありがとうございました。 今回質問させていただきましたプログラムは、TCP/IPソケットプログラミングJava編という本の最初の章のものです。 これからこの本を進めていきます。また、分からないものがありましたら、質問を投稿させていただきます。もしお時間がございましたら教えていただきたいと思っております。 f272さん、たくさんのアドバイスありがとうございました。

  • f272
  • ベストアンサー率46% (8625/18445)
回答No.7

私はあなたのネットワーク環境を知らないので適切なアドバイスをすることは非常に困難だということは理解していますか? > どのように確認するのでしょうか? 物理的に接続されているかから始まって,接続を邪魔するプログラム(アンチウイルスプログラムとか)が走ってないかとか色々です。で,そういうことが面倒なので,多分ちゃんと接続できているんだろうと想像したメールサーバの話をしています。 で,今問題にしているUbuntuマシンは,メールサーバにアクセスしているノートPCと同じネットワークに接続されているんですか?そのメールサーバのアドレスやポート番号はわかっているんですか?全てイエスなら,Ubuntuマシンからそれらの情報を使って接続してみてください。やり方は既に書いたとおりです。 なお,ここでメールの設定とかそんな話が出てくるとは吃驚です。関係のないプログラム(メールクライアント)でどんな設定をしていても関係ないのですから。必要なのはサーバの情報です。それを使ってあなたのプログラムでサーバに接続し,アクセスするのです。 もう1つメールサーバを使うこととは別の提案で,ウエブサーバに接続してみましょうか? もしUbuntuマシンがインターネットに接続されているのでしたら,プログラムの引数を okwave.jp test 80 にしてテストしてみてください。ただしこうすると while (totalBytesRcvd < byteBuffer.length){ このループを無限に繰り返すことになりますから,プログラムを強制終了するか,そうでなければそのwhile文の直前に System.out.println("OK"); socket.close(); System.exit(0); を挿入して,ループに入る前にプログラムを明示的に終了させることが必要です。

debukawa
質問者

お礼

回答ありがとうございます。 ノートPCでメールサーバのアドレスとポート番号を見て、 このように引数部分に入力しました。 メールサーバのアドレス word ポート番号 すると、 Connected to server...sending echo string Received: +OK と表示されました。 今までは、この表示すらされなかったので、とても進歩したと思います。本当にありがとうございます。 Received: +OK の部分ですが、ここは引数欄でwordに該当する文字列が出力されると思っていましたが違うのでしょうか? 私は、引数の欄には、testと入力していました。 ほかにもwordと入力してもReceived: +OKとなります。 何を入力してもReceived: +OKとなるのでしょうか?

  • f272
  • ベストアンサー率46% (8625/18445)
回答No.6

> このプログラムはおかしいですか? プログラムがおかしいんじゃなくて,動作環境がおかしいんでしょ。 このプログラムを実行している機械から,ちゃんと指定したサーバの指定したポートに接続できるの?それを確認してくださいね。 または,もともと接続が確認できているサーバとポートを見つけてきてそれを指定してもいいよね。この方針だと,以前にも言ったけど,例えば自分の使っているメールサーバがあるでしょ。で,その機械からメールサーバに対してメールを送ることができるよね。こういう状況ならそのメールサーバに対して接続要求をするようにすれば良いわけで,メールサーバなら25番ポートでsmtpプロトコルが使えてHELOと挨拶すれば返事をくれると思うので xxx.xxx.xxx.xxx HELO 25 と指定してみたらどうでしょう,と提案した次第です。 とにかく接続ができる環境で,プログラムを実行してくださいね。

debukawa
質問者

お礼

回答ありがとうございます。いつもすみません。 >このプログラムを実行している機械から,ちゃんと指定したサーバの >指定したポートに接続できるの?それを確認してくださいね。 どのように確認するのでしょうか? 私は、Ubuntuでプログラミングをしています。メールはノートPCで行うので、Ubuntu(プログラムを動かしている機械)のメールの設定はしていません。 このメールの設定をしていない機械(Ubuntu)ではメールサーバに接続要求をすることはできないのでしょうか?プログラムをちゃんと実行させるためには、メールの設定をする必要がありますか?

  • f272
  • ベストアンサー率46% (8625/18445)
回答No.5

Exception in thread "main" java.net.ConnectException: Connection refused ということは文字通り接続を拒否されているのです。 サーバ名は127.0.0.1にしてる? 本当に127.0.0.1が存在する?環境が分からないけど,例えばシェル(コマンドプロンプト)からping 127.0.0.1としてエラーにならない? まあ,127.0.0.1でなくてもちゃんと存在して自分が接続できるはずのサーバのアドレスを指定してやれば,少なくともConnected to server...sending echo stringは出てくると思うよ。

debukawa
質問者

お礼

回答ありがとうございます。 コマンドプロンプトでping 127.0.0.1と入力すると、 PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data. 64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.017 ms となりました。 サーバ名を127.0.0.1にして実行しましたが同じエラーです。 質問当初とはソースコードを少し変えたので、下に載せます。 このプログラムはおかしいですか? package socket_33; import java.net.*; // Socketに必要 import java.io.*; // IOException,Input/OutputStreamに必要 public class TCPEchoClient { public static void main(String[] args) throws IOException { if ((args.length < 2) || (args.length > 3)) // 引数の数が正しいかどうかを調べる throw new IllegalArgumentException("Parameter(s): <127.0.0.1> <test> [<25>]"); String server = args[0]; // サーバ名またはIPアドレス // デフォルトの文字エンコード方式を使って入力Stringをバイトに変換する byte[] byteBuffer = args[1].getBytes(); int servPort = (args.length == 3) ? Integer.parseInt(args[2]) : 7; // サーバの指定されたポートに接続するソケットを作成する Socket socket = new Socket(server, servPort); System.out.println("Connected to server...sending echo string"); InputStream in = socket.getInputStream(); OutputStream out = socket.getOutputStream(); out.write(byteBuffer); // エンコードされた文字列をサーバに送信する // サーバから同じ文字列を受信する int totalBytesRcvd = 0; // これまでに受信した合計バイト数 int bytesRcvd ; // 前回の読み込みで受信したバイト数 while (totalBytesRcvd < byteBuffer.length){ if ((bytesRcvd = in.read(byteBuffer,totalBytesRcvd,byteBuffer.length - totalBytesRcvd)) == -1) throw new SocketException("Connection closed prematurely"); totalBytesRcvd += bytesRcvd; } System.out.println("Received: " + new String(byteBuffer)); socket.close(); // ソケットとストリームをクローズする } }

  • f272
  • ベストアンサー率46% (8625/18445)
回答No.4

あなたのエラーを見ると Could not find the main class: TCPEchoClient. Program will exit. といわれているようだけど,メインクラスは socket_33.TCPEchoClient のはずじゃなかったの?もしかすると#3であげたページを見て変えちゃったのかな?

debukawa
質問者

お礼

回答ありがとうございます。 はい、変えてしまいました。 メインクラスをsocket_33.TCPEchoClient としたところ、違うエラーが出ました。 Exception in thread "main" java.net.ConnectException: Connection refused at java.net.PlainSocketImpl.socketConnect(Native Method) at java.net.PlainSocketImpl.doConnect(Unknown Source) at java.net.PlainSocketImpl.connectToAddress(Unknown Source) at java.net.PlainSocketImpl.connect(Unknown Source) at java.net.SocksSocketImpl.connect(Unknown Source) at java.net.Socket.connect(Unknown Source) at java.net.Socket.connect(Unknown Source) at java.net.Socket.<init>(Unknown Source) at java.net.Socket.<init>(Unknown Source) at socket_33.TCPEchoClient.main(TCPEchoClient.java:19) 調べたら、ソケットの接続を試行中にエラーが発生したことの 通知だと書いてありました。 19行目のなにがおかしいのでしょうか?

debukawa
質問者

補足

もうしわけございません。 ソースコードの /** * @param args */ の部分をけしていたため、行の数字が変わっていました。 実際は24行目がおかしいというメッセージが出ています。 この部分です。 Socket socket = new Socket(server, servPort);

  • f272
  • ベストアンサー率46% (8625/18445)
回答No.2

ちょっとeclipseをインストールしてみた#1です。 同じエラーが出るということは,全く引数が渡されていないということ。 > 「サーバ名」…IPアドレス > 「サーバに渡す文字列」…word > 「サーバのポート番号」…123 > としました。 具体的に何をしたのかな? Run(実行) - Run Configurations...(実行) で出てくるダイアログでMain(メイン)タブのところではなく,Arguments(引き数)タブのProgram arguments(プログラム引き数)にちゃんと書き込んでいるのかな?

debukawa
質問者

お礼

15行目のthrow new IllegalArgumentException("Parameter(s): <Server> <word> [<Port>]");の部分に <IPアドレス> <word> [<123>]");としただけです。 >Run(実行) - Run Configurations...(実行) で出てくるダイアログで >Main(メイン)タブのところではなく,Arguments(引き数)タブの? >Program arguments(プログラム引き数)にちゃんと書き込んでいるのか >な? 書き込んでいません。

debukawa
質問者

補足

プログラム引数の欄にはどのように書けばよいのでしょうか?

  • f272
  • ベストアンサー率46% (8625/18445)
回答No.1

このプログラムが何をするプログラムなのか理解しているのだろうか? まあ,何も分かっていなくても TCPEchoClient.java:15 と書かれているのだから,15行目をみて throw new IllegalArgumentException("Parameter(s): <Server> <word> [<Port>]"); と書いてあるところに注目するよね。そうすると確かに java.lang.IllegalArgumentException が呼ばれていて Parameter(s): <Server> <word> [<Port>] を返すことになっている。これが呼ばれる条件は if ((args.length < 2) || (args.length > 3)) なのだから引数の数を2か3にすればよい。で,期待されている引数は書いてある通り 「サーバ名」と「サーバに渡す文字列」と(オプショナルに)「サーバのポート番号」 だと分かる。 ついでに throw new SocketException("Connection closed prenmaturely"); これは,エラーにはならないが throw new SocketException("Connection closed prematurely"); の間違いだろう。

debukawa
質問者

お礼

回答ありがとうございます。 「サーバ名」…IPアドレス 「サーバに渡す文字列」…word 「サーバのポート番号」…123 としました。これで実行しても同じエラーが出ます。 なにがいけないのでしょうか?

関連するQ&A