こんにちは、私は今サーバとクライアント間で通信を行うプログラムを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も見ています
-
とっておきの「夜食」教えて下さい
真夜中に小腹がすいたときにこっそり作るメニュー、こっそり家を抜け出して食べに行くお店… 人には言えない、けど自慢したい、そんなあなたの「とっておきの夜食」を教えて下さい。
-
秘密基地、どこに作った?
小さい頃、1度は誰もが作ったであろう秘密基地。 大人の今だからこそ言える、あなたの秘密基地の場所を教えてください!
-
【お題】ヒーローの謝罪会見
【大喜利】 怪人の侵略に気づくのが遅れ、それを防げなかった戦隊ヒーローの謝罪会見で出た発言
-
この人頭いいなと思ったエピソード
一緒にいたときに「この人頭いいな」と思ったエピソードを教えてください
-
ギリギリ行けるお一人様のライン
おひとり様需要が増えているというニュースも耳にしますが、 あなたが「ギリギリ一人でも行ける!」という場所や行為を教えてください
-
ソケット通信 同じポート番号でn対1はできない?
C言語・C++・C#
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・【大喜利】【投稿~12/2】 国民的アニメ『サザエさん』が打ち切りになった理由を教えてください
- ・ちょっと先の未来クイズ第5問
- ・【お題】ヒーローの謝罪会見
- ・これが怖いの自分だけ?というものありますか?
- ・スマホに会話を聞かれているな!?と思ったことありますか?
- ・それもChatGPT!?と驚いた使用方法を教えてください
- ・見学に行くとしたら【天国】と【地獄】どっち?
- ・【大喜利】【投稿~11/22】このサンタクロースは偽物だと気付いた理由とは?
- ・お風呂の温度、何℃にしてますか?
- ・とっておきの「まかない飯」を教えて下さい!
- ・2024年のうちにやっておきたいこと、ここで宣言しませんか?
- ・いけず言葉しりとり
- ・土曜の昼、学校帰りの昼メシの思い出
- ・忘れられない激○○料理
- ・あなたにとってのゴールデンタイムはいつですか?
- ・とっておきの「夜食」教えて下さい
- ・これまでで一番「情けなかったとき」はいつですか?
- ・プリン+醤油=ウニみたいな組み合わせメニューを教えて!
- ・タイムマシーンがあったら、過去と未来どちらに行く?
- ・遅刻の「言い訳」選手権
- ・好きな和訳タイトルを教えてください
- ・うちのカレーにはこれが入ってる!って食材ありますか?
- ・おすすめのモーニング・朝食メニューを教えて!
- ・「覚え間違い」を教えてください!
- ・とっておきの手土産を教えて
- ・「平成」を感じるもの
- ・秘密基地、どこに作った?
- ・カンパ〜イ!←最初の1杯目、なに頼む?
- ・この人頭いいなと思ったエピソード
- ・あなたの「必」の書き順を教えてください
- ・ギリギリ行けるお一人様のライン
- ・10代と話して驚いたこと
- ・大人になっても苦手な食べ物、ありますか?
- ・14歳の自分に衝撃の事実を告げてください
- ・家・車以外で、人生で一番奮発した買い物
- ・人生最悪の忘れ物
- ・あなたの習慣について教えてください!!
- ・都道府県穴埋めゲーム
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
TCP/IP通信時のサーバーからの受信
-
ソケットのクローズについて
-
recv関数でフリーズしてしまう
-
WinSockでの通信プログラムがう...
-
Socket通信の0バイト受信について
-
closeされたsocketへの動作につ...
-
ソケット通信 同じポート番号...
-
Winsockで接続待ちタイムアウト...
-
Delphi で作成中 DLL の中で Pr...
-
winsockを使った通信での同時接...
-
【ajax】 XMLHttpRequestオブジ...
-
VC6.0ソケット通信プログラムに...
-
異なる言語間でのソケット通信...
-
UDPで受信終了の合図を出して受...
-
UDP通信する時に、相手にどうや...
-
相手のIPアドレスを取得する方法
-
TCP/IP通信でのコネクシ...
-
Javaプログラム同士のプロセス...
-
Macターミナルで実行中のプログ...
-
C# シリアル通信でデータ受信...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
TCP/IP通信時のサーバーからの受信
-
エクセル VBA でのCOMポート...
-
ソケットのrecvの戻り値が0
-
recv関数でフリーズしてしまう
-
VB6のwinsockでconnectできない
-
UDP通信する時に、相手にどうや...
-
UDP通信におけるbind関数について
-
ソケットでクライアントのipア...
-
Socket通信の0バイト受信について
-
ソケット通信 同じポート番号...
-
UdpClient 送信元のIPアドレ...
-
Winsockで接続待ちタイムアウト...
-
ソケットのクローズについて
-
ソケットを用いた1対多通信につ...
-
Connectエラーが出てしまう・・...
-
非ブロッキングソケットのrecv...
-
CreateFile関数でCOMポートが開...
-
Socket通信を待ち受け状態にす...
-
同じLAN内パソコンのIPアドレス...
-
WinSockでの通信プログラムがう...
おすすめ情報