ユーザーがクライアントまたはサーバーの役割を選択する必要があるチャット プログラムを作成しました。この要件を取り除くための私のアプローチは、すべてのユーザーがメッセージを取得する独自のサーバーを起動することです。これにより、サーバーを間に挟むことなく、2 つのクライアントが他のクライアントと通信できるようになります。
現在、クライアント側が送信を行い、サーバーが受信を行うようにプログラムを修正しました。
これらの変更が行われるまで、2 つのプログラム間の通信は完全に正常に機能していたことに注意してください。ただし、いくつかの変更を加えたので、ソケットを作成した時点でエラーが発生します。
問題が発生するまでの私のプログラムの流れは次のとおりです。
- プログラム開始
- サーバーが自動的に起動し、ローカル ポート 6666 にバインドされます
- 接続構成がポップアップ表示され、ユーザーが保存ボタンをクリックします (ターゲット ホストとポートが保存されます)。
- ユーザーが接続ボタンをクリックする
- プログラムがクライアント スレッドを作成する
- スレッドがソケットを作成し、送信ストリームを開始します
いくつかのデバッグの後、このソケットが作成されていないことがわかりました。
フローがこの段階 (リストの最後の項目) に入ると、「最初のテスト」のみが実行されます。
public void run() {
System.out.println("First test");
createConnection();
System.out.println("Second test");
initiateIO();
}
private void createConnection() {
try {
socket = new Socket(host, port);
} catch (UnknownHostException e) {
OutputUtil.showErrorMessage("Couldn't bind socket to unknown host", "Unknown host");
} catch (IOException e) {
OutputUtil.showErrorMessage("General IO error at creating client socket", "IO error");
}
}
private void initiateIO() {
try {
outbound = new PrintWriter(socket.getOutputStream(), true);
} catch (IOException e) {
OutputUtil.showErrorMessage("Couldn't load IO streams from client", "IO Error");
}
}
出力:
Console: First test
Popup: General IO error at creating client socket
Console: Second test
Console: NPE at `outbound.close()`
を作成するときにソケットからのメソッドが呼び出されることを考慮して、NPE は最初のエラーの結果であると想定していますPrintWriter
。また、最初のエラーが表示されるまでに約 10 秒かかることにも注意してください。
最初は、ローカル サーバーと他のクライアントとの接続の両方がポート 6666 を使用しているため、エラーが発生したのではないかと考えましたが、ポート 6667 でリンクを作成した後も問題は発生しました。これは、レビューすると理にかなっています。
デバッガーが が初期化されている行を指している場合outbound
(「2 番目のテスト」メッセージの後、ソケットの値はnull
.
私の質問は、ソケットを作成できないのはなぜですか? ドキュメントは指定するだけです
IOException - ソケットの作成時に I/O エラーが発生した場合。
これはあまり役に立ちません。
より良い概要を得るために、完全なソースコードはここにあります。
編集:最初のメインエラーからスタックトレースを出力しました。
java.net.ConnectException: Connection timed out: connect
at java.net.DualStackPlainSocketImpl.connect0(Native Method)
at java.net.DualStackPlainSocketImpl.socketConnect(Unknown Source)
at java.net.AbstractPlainSocketImpl.doConnect(Unknown Source)
at java.net.AbstractPlainSocketImpl.connectToAddress(Unknown Source)
at java.net.AbstractPlainSocketImpl.connect(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 core.Client.createConnection(Client.java:30)
at core.Client.run(Client.java:64)
at java.lang.Thread.run(Unknown Source)