プロが教える店舗&オフィスのセキュリティ対策術

こんにちは、私は今サーバとクライアント間で通信を行うプログラムをjavaで作ろうとしています。
具体的には、クライアント側で入力した数値の5倍した値をサーバ側が返すというものです。
今のところ、クライアント側のリクエストに対するレスポンスをサーバが返すことはできるのですが、複数のクライアントからサーバにリクエストを送ると、それに対するレスポンスが全てのクライアントに返されるようになっています。
これをリクエストがあったクライアントにだけ返すように修正したいのですが、
解決方法が分かる方がいれば、教えていただけないでしょうか。

それと、プログラムを全て添付しようとしたのですが、文字数の都合で質問は2つに分けています。
今回の質問で載せているのは、サーバ側のプログラムです。
見にくいかもしれませんが、ご了承下さい。

ちなみに、これが原因か分かりませんが、サーバ、クライアント等の実行は、同じPCで行っていて、サーバ、クライアント側でソケットを生成する際のIPアドレス、ポート番号は全て同じものです。

import java.io.*;
import java.net.*;
import java.util.*;

/*
* サーバクラス
* 第一引数:ポート番号(省略可)
*/
public class Server {
private static int DEFAULT_PORT = 6000; // ポート番号
private static ServerSocket serverSocket;//ソケット
private static Vector connections;//クライアントごとのソケットを管理

//渡された値を五倍するメソッド
public static void calculate(String name,int number) {
int result = -99;
if (connections != null) {
for (Enumeration e = connections.elements(); e.hasMoreElements();) {
try {
PrintWriter printWriter = new PrintWriter(((Socket) e.nextElement()).getOutputStream());
result = number*5;
printWriter.println(name+">"+result);//出力用ストリームに書き込む。
printWriter.flush();//強制的にデータを書き込む。
}
catch (IOException ex) { }
}
}
System.out.println(name+">"+result);
//return result;
}

/*
新たなクライアントとの接続を追加する。
*/
public static void addConnection(Socket socket) {
if (connections == null) {
connections = new Vector();
}
connections.addElement(socket);
}

// deleteConnectionメソッド
// クライアントとの接続を削除する
public static void deleteConnection(Socket socket) {
//System.out.println("サーバを起動します。");
if (connections != null) {
connections.removeElement(socket);
}
}

// サーバソケットを作り、クライアントからの接続を待ち受けます
public static void main(String[] arg) {
int port = Server.DEFAULT_PORT;

if (arg.length > 0) {
port = Integer.parseInt(arg[0]);
}

try {
serverSocket = new ServerSocket(port);//サーバソケットの生成
System.out.println("サーバを起動します。");
}
catch (IOException e) {
System.err.println(e);
System.exit(1);
}

while (true) {
try {
Socket socket = serverSocket.accept();//クライアントからの接続を待つ。
addConnection(socket);//クライアントとの接続を追加する。
Thread clientProc = new Thread(new ClientProc(socket));//スレッド生成
clientProc.start();//スレッド起動
}catch (IOException e){
System.err.println(e);
}
}
}

}

/*
* クライアントとのコネクション管理用スレッド
*/
class ClientProc implements Runnable{

private Socket socket;//データの送受信部
private BufferedReader input;//入力用ストリームからデータを読み取る
private PrintWriter output;//データを出力用ストリームに書き込む
private int number =-99;
private String name ="";
private Server server=null;

public ClientProc(Socket socket) throws IOException{
this.socket=socket;
input = new BufferedReader(new InputStreamReader(socket.getInputStream()));//入力用ストリーム生成(クライアントからの入力データを読み込む。)
output = new PrintWriter(socket.getOutputStream());//出力用ストリーム生成(サーバ側の出力データを書き込む。)
}


public void run() {
try{
//クライアントの名前が入力されるまで待つ。
while (number==-99){
output.print("名前を入力: ");//出力用ストリームに書き込む。
//output.print(this.toString());//追加(アドレスとポート出力)
output.flush();
name=input.readLine();//入力用ストリームから読み込む。
output.print("5倍したい数字を入力: ");//出力用ストリームに書き込む。
output.flush();
number=Integer.parseInt(input.readLine());//入力用ストリームから読み込む。
}

//String line = input.readLine();
String line = "";
//quitが入力されるまで、全てのクライアントにメッセージを送る。
while(!"quit".equals(line)){
//Server.sendAll( "5倍すると"+number1*5+"になります。");//受け取ったメッセージを全てのクライアントに送る。
Server.calculate(name,number);
line=input.readLine();//入力用ストリームから読み込む
}

//quitが入力されると、コネクションを削除し、ソケットを閉じる。
Server.deleteConnection(socket);
socket.close();
}catch(IOException e){
try{
socket.close();
}catch (IOException e2){

}
}
}

}

A 回答 (1件)

メソッド calculate(String name,int number) が、


全てのクライアントに返される様に実装しているため。

リクエストがあったクライアントへの出力である output が、
メソッド calculate の呼び出し元に存在するので、
せっかくならばこれを使った実装に置き換えれば解決

案1
メソッド void calculateTo(PrintWriter output, String name,int number) に置き換え
connections を使わず、引数の output にだけ出力

案2
メソッド String getCalculation(String name,int number) に置き換え
メソッドでは出力せずに計算した文字列を返す。
呼び出し元で計算結果を output に出力
    • good
    • 1
この回答へのお礼

ご指摘いただいたとおり、calculateメソッドでoutputを引数として受け取って、そのoutputにだけ出力するように変更したところ、目的のクライアントにだけレスポンスを返すことができました。
本当にありがとうございました。

お礼日時:2017/01/15 18:00

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!