
こんにちは、私は今サーバとクライアント間で通信を行うプログラムを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){
}
}
}
}
No.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 に出力
ご指摘いただいたとおり、calculateメソッドでoutputを引数として受け取って、そのoutputにだけ出力するように変更したところ、目的のクライアントにだけレスポンスを返すことができました。
本当にありがとうございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- Java java 入力 3 4 3 出力 ABC DEFG HIJ このようなプログラムの書き方を教えてくだ 2 2022/07/15 14:18
- Java javaでのプログラム(配列)について質問です. 2 2022/10/14 22:27
- Java JavaのSingletonパターンのprivateの持つ意味が分かりません。 5 2022/06/12 10:38
- C言語・C++・C# C# DatagridviewにExcelシートを反映するとエラーが出る 2 2023/05/06 17:12
- Ruby 【JAVA】数字をひし形に出力するプログラムについて 2 2022/07/11 23:32
- PHP ここでの ②if($su_d<>"")の比較演算子 を使う理由は 1 2022/03/26 02:33
- C言語・C++・C# 大量のデータを読み込んで表示する速度を改善したい 8 2023/05/07 13:29
- Java Java 配列<選挙> 4 2023/07/31 15:07
- PHP htmlspecialcharsが機能していないです。 バグですか? 1 2022/04/05 01:22
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
相手のIPアドレスを取得する方法
-
Winsockで接続待ちタイムアウト...
-
TCP/IP通信時のサーバーからの受信
-
VB6‥ソケットについて
-
C++BuilderでHTTP通信する方法...
-
Winsockプログラミング Connec...
-
ネットワークプログラミングに...
-
PCからlprで送信したジョブを別...
-
recv関数でフリーズしてしまう
-
エクセル VBA でのCOMポート...
-
UDPを使って通信速度測定プログ...
-
VB6のwinsockでconnectできない
-
CreateFile関数でCOMポートが開...
-
WinSockでの通信プログラムがう...
-
Winsockを利用したファイルの送...
-
UdpClient 送信元のIPアドレ...
-
C言語(Windows)から...
-
RS-232Cのポート番号を知りたい
-
VBのソケット通信(winsock)の...
-
ソケット通信の送受信遅延-02 ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
TCP/IP通信時のサーバーからの受信
-
UDP通信におけるbind関数について
-
Winsockで接続待ちタイムアウト...
-
UDP通信する時に、相手にどうや...
-
エクセル VBA でのCOMポート...
-
Socket通信の0バイト受信について
-
VB6のwinsockでconnectできない
-
ソケットでクライアントのipア...
-
ソケットを用いた1対多通信につ...
-
ソケットのクローズについて
-
ソケットのrecvの戻り値が0
-
UdpClient 送信元のIPアドレ...
-
相手のIPアドレスを取得する方法
-
recv関数でフリーズしてしまう
-
closeされたsocketへの動作につ...
-
送信したデータの一部が文字化...
-
UDP通信(SNMP)したいが、うま...
-
ソケット通信
-
Connectエラーが出てしまう・・...
-
WinSockでの通信プログラムがう...
おすすめ情報