単純なネットワークテストプログラムを実行しても結果が出ないようにしようとしています。
サーバ:
import Java.io.*;
import Java.net.*;
public class ServerTest {
public static void main(String[] args) {
final int PORT_NUMBER = 44827;
while(true) {
try {
//Listen on port
ServerSocket serverSock = new ServerSocket(PORT_NUMBER);
System.out.println("Listening...");
//Get connection
Socket clientSock = serverSock.accept();
System.out.println("Connected client");
//Get input
BufferedReader br = new BufferedReader(new InputStreamReader(clientSock.getInputStream()));
System.out.println(br.readLine());
br.close();
serverSock.close();
clientSock.close();
} catch(Exception e) {
e.printStackTrace();
}
}
}
}
クライアント:
import Java.io.*;
import Java.net.*;
public class ClientTest {
public static void main(String[] args) throws IOException {
final int PORT_NUMBER = 44827;
final String HOSTNAME = "xx.xx.xx.xx";
//Attempt to connect
try {
Socket sock = new Socket(HOSTNAME, PORT_NUMBER);
PrintWriter out = new PrintWriter(sock.getOutputStream(), true);
//Output
out.println("Test");
out.flush();
out.close();
sock.close();
} catch(Exception e) {
e.printStackTrace();
}
}
}
ホスト名に127.0.0.1または内部IPを使用すると、プログラムは正常に動作します。しかし、外部IPアドレスに切り替えるたびに、Java.net.ConnectException: Connection refused: connect
エラー。
私はこのような珍しいポートを故意に選び、それが問題であるかどうかを確認しましたが、運がありませんでした。 telnetを使用しても問題なく接続できますが、canyouseeme.orgでポートにアクセスしようとすると、接続がタイムアウトしたことがわかります。 Windowsのデフォルトファイアウォールとルーターファイアウォールを含むすべてのファイアウォールとウイルス対策を無効にしようとしましたが、すべてのポートが転送され、DMZが有効になっています。それでも接続がタイムアウトしたと表示されます。Comcastを私のISP、そして私はそれらがそのようなランダムなポートをブロックすることを疑っています。
パケットトレーサーを使用すると、TCPトラフィックが表示され、コンピューターがSYNを送信し、RST/ACKを受信するため、標準のブロックされたポートのように見え、他の疑わしいパケットトラフィックは発生していません。
この時点で何が起こっているのかわかりません。私は知っているすべてのトリックをほとんど試しました。なぜポートがブロックされているのか、あるいは少なくともプログラムを機能させるための何らかの方法を知っている人がいれば、とても役に立ちます。
それが価値があることについては、あなたのコードは私のシステムで正常に動作します。
私はそれを言いたくないのですが、ファイアウォールの問題(すでにトリプルチェックされていることはわかっています)または Comcastの問題 のように思えます。私は ISPをテストする を行います。
これらの問題は、次の状況で発生します。
クライアントとサーバーのいずれかまたは両方がネットワークにありません。
サーバーが実行されていません。
サーバーは実行されていますが、ポートをリッスンしていません。クライアントが接続しようとしています。
ファイアウォールは、ホストとポートの組み合わせでは許可されていません。
ホストポートの組み合わせが正しくありません。
接続文字列のプロトコルが正しくありません。
問題を解決する方法:
まず、宛先サーバーにpingします。それが適切にpingしている場合は、クライアントとサーバーの両方がネットワーク上にあります。
Telnetを使用してサーバーのホストとポートに接続してみます。接続できる場合は、クライアントコードにいくつかの間違いがあります。
おそらく、サーバーソケットはlocalhostアドレスにのみバインドされています。コンストラクタの3引数形式を使用して、特定のIPアドレスにバインドできます。
ルーターを使用してインターネットに接続していると思います。パブリックが内部ネットワークにアクセスできるようにするには、ポート転送を行う必要があります。ご覧ください どのように取得しますJavaパブリックIPで動作するソケット?
ポートフォワーディングに関するブログ投稿も書いています。ぜひご覧になってください:) http://happycoders.wordpress.com/2010/10/03/how-to-setup-a-web-server -by-yourself /
しかし、私はまだパブリックIP経由でこれにアクセスすることができず、今それを処理しています...
クライアントがサーバーの前に起動することもあり、接続を設定しようとしたときに実行中のサーバーが見つからなかったため、同じ問題が発生しました。
私の最初の(それほどエレガントではない)解決策は、sleepメソッドを使用してしばらくの間クライアントを停止することでした:
_try {
Thread.sleep(1000);
}
catch (InterruptedException e) {
e.printStackTrace();
}
_
このコードは、クライアント接続の直前、例ではSocket sock = new Socket(HOSTNAME, PORT_NUMBER);
の直前に使用します
私の2番目のソリューションは this の回答に基づいていました。基本的に、クライアントクラスにメソッドを作成しました。このメソッドはサーバーへの接続を試み、接続が失敗した場合、2秒待ってから再試行します。これは私の方法です:
_private Socket createClientSocket(String clientName, int port){
boolean scanning = true;
Socket socket = null;
int numberOfTry = 0;
while (scanning && numberOfTry < 10){
numberOfTry++;
try {
socket = new Socket(clientName, port);
scanning = false;
} catch (IOException e) {
try {
Thread.sleep(2000);
} catch (InterruptedException ie) {
ie.printStackTrace();
}
}
}
return socket;
}
_
ご覧のとおり、このメソッドはソケットを10回作成しようとし、その後、ソケットに対してnull値を返します。注意して結果を確認してください。
コードは次のようになります。
_Socket sock = createClientSocket(HOSTNAME, PORT_NUMBER);
if(null == sock){ //log error... }
_
この解決策は私を助けました、それがあなたにも役立つことを願っています。 ;-)