- PR -

ServerSocketプログラムについて

1
投稿者投稿内容
ハマ
会議室デビュー日: 2004/03/26
投稿数: 5
投稿日時: 2004-03-26 11:46
Socketで以下のようなプログラムを作成して、サーバーに対していくつまで、ソケット
を同時にできるかをテストしておりますが、Clent側から16個しかSocketをnewすること
ができません。それ以上作成しようとすると、下記のConnectExceptionが発生します。
ServerSocketはbacklogを指定しないと、デフォルトで50個までaccept()メソッドの
キューにいれることができると思いますので、最低でも50個以上はソケット接続が確立
すると思うのですが、私の認識は間違っているのでしょうか?
それとも、何か他の原因なのでしょうか?

以下にエラーとプログラムの一部分を記載させて頂きます。

・エラー
java.net.ConnectException: Connection refused: connect
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:305)
at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:171)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:158)
at java.net.Socket.connect(Socket.java:452)
at java.net.Socket.connect(Socket.java:402)
at java.net.Socket.<init>(Socket.java:309)
at java.net.Socket.<init>(Socket.java:124)
at ClientSocketTest.run(ClientSocketTest.java:14)

・Server側プログラム
public static void main(String[] args) {
 ServerSocket serverSocket = null;
 try {
//サーバソケットを作成する
serverSocket = new ServerSocket(10000, 100);
System.out.println("サーバ起動");

Channel channel = new Channel(100);
channel.startWorkers();

while(true){
//リクエストに対して待機する
Socket clientSocket = serverSocket.accept();
ClientThread clientThread = new ClientThread(clientSocket,channel);
clientThread.socketAdd();
}

・Client側プログラム
public class ClientSocketTest extends Thread {

static int threadNumber = 0;

Socket socket = null;

public void run() {

try {
//ソケットを作成
socket = new Socket("localhost", 10000);

//SocketオブジェクトからOutputStreamオブジェクトを取得する
OutputStream out = socket.getOutputStream();
BufferedWriter bWriter = new BufferedWriter(new OutputStreamWriter(out));

//SocketオブジェクトからInputStreamオブジェクトを取得する。
InputStream in = socket.getInputStream();
BufferedReader bReader = new BufferedReader(new InputStreamReader(in));
String readSt;

while(true) {
//文字列"quit"をサーバに送信する
String requestData = "quit";
bWriter.write(requestData, 0, requestData.length());
bWriter.newLine(); //改行をつける
bWriter.flush(); //フラッシュしてデータを送信する
System.out.println(Thread.currentThread().getName() + " Client : " + requestData);

//サーバのレスポンスを取得する
readSt = bReader.readLine();
System.out.println(Thread.currentThread().getName() + " Server : " + readSt);

//bWriter.close();
//bReader.close();
}

} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
System.err.println("エラーが発生したスレッドの名前 : " + Thread.currentThread().getName());
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} /*finally {
if(socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}*/
}
public static void main(String[] args) {

for(int i = 0; i < 100;i++) {

ClientSocketTest clientSockect = new ClientSocketTest();
clientSockect.start();
threadNumber++;
System.out.println("作成したクライアントの数 : " + threadNumber);
}
}
}

少し、見ずらくなってしまいましたが、何かアドバイスをお願い致します。
それでは失礼致します。
シュン
ぬし
会議室デビュー日: 2004/01/06
投稿数: 328
お住まい・勤務地: 東京都
投稿日時: 2004-03-26 17:31
サーバー側のCannelとClientThreadが何をやっているのかわかりませんので、
どうにも分かりません。

とりあえずローカルで100個のソケット接続を確立するテストソースを書いて
みました。(プロセスをkillするまで100個のソケットが接続したままになり
ます。)

私の環境(Windows2000、JDK1.4.2_03)では問題なく動きますが、そちらでは
どうですか?

コード:
import java.net.ServerSocket;
import java.net.Socket;

public class SocketTest {

	public static void main(String[] args) throws Exception{
		final ServerSocket ss = new ServerSocket(10000,100);
		new Thread(){
			public void run(){
				try{while(true){ss.accept();}}
				catch(Exception e){
					System.out.println("Server failed");
					e.printStackTrace();
				}
			}
		}.start();
		
		
		for( int i = 0 ; i < 100 ; i++){
			final int current = i;
			new Thread(){
				public void run(){
					try{
						synchronized(this){
							Socket s = new Socket("localhost",10000);
							System.out.println("Socket created:"+current);
							this.wait();
						}
					}
					catch(Exception e){
						System.out.println("Socket create failed:"+current);
						e.printStackTrace();
					}
				}
			}.start();
		}
	}
}


ハマ
会議室デビュー日: 2004/03/26
投稿数: 5
投稿日時: 2004-03-29 11:48
御返答ありがとうございます。テストプログラムは私の環境(Windows2000、JDK1.4.2_03)
でも動作致しました。やはり他に原因があるのですね・・・。

しかし、一つ疑問があるのですが、テストプログラムの下記の部分のsynchronizedは
何故必要なのでしょうか?

synchronized(this){
  Socket s = new Socket("localhost",10000);
  System.out.println("Socket created:"+current);
  this.wait();
}


確かに、synchronizedを外して動かしてみると、this.wait()の箇所で下記のエラーが
発生します。
このエラーの意味があまりよくわかりません。

java.lang.IllegalMonitorStateException: current thread not owner
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:429)
at SocketTest$2.run(SocketTest.java:27)

私の知識不足で申し訳ありませんが、御返答宜しくお願い致します。
山本 裕介
ぬし
会議室デビュー日: 2003/05/22
投稿数: 2415
お住まい・勤務地: 恵比寿
投稿日時: 2004-03-29 11:59
>確かに、synchronizedを外して動かしてみると、this.wait()の箇所で下記のエラーが
>発生します。
>このエラーの意味があまりよくわかりません。
API を御参照ください。
http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Object.html#wait()
1

スキルアップ/キャリアアップ(JOB@IT)