こんにちは、私は今サーバとクライアント間で通信を行うプログラムを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ランキング
-
Winsockを使わずにVBでSocketを...
-
TCP/IP通信時のサーバーからの受信
-
VB6のwinsockでconnectできない
-
UDPを使って通信速度測定プログ...
-
ソケットのrecvの戻り値が0
-
winsockを使った通信での同時接...
-
オセロゲームのオンラインゲーム
-
MFCソケットについて
-
VC++でのソケット通信について
-
Javaプログラム同士のプロセス...
-
C#とTCP/IPを利用したサーバー...
-
Socket通信の0バイト受信について
-
エクセル VBA でのCOMポート...
-
Winsockで接続待ちタイムアウト...
-
異なる言語間でのソケット通信...
-
UdpClient 送信元のIPアドレ...
-
名前付きパイプの通信ポートに...
-
ポート番号0について
-
JavaでBASIC認証突破
-
recv関数でフリーズしてしまう
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
TCP/IP通信時のサーバーからの受信
-
エクセル VBA でのCOMポート...
-
UDP通信する時に、相手にどうや...
-
UDP通信におけるbind関数について
-
UdpClient 送信元のIPアドレ...
-
Winsockで接続待ちタイムアウト...
-
recv関数でフリーズしてしまう
-
ソケットのクローズについて
-
ソケットのrecvの戻り値が0
-
Socket通信の0バイト受信について
-
ソケット通信 同じポート番号...
-
相手のIPアドレスを取得する方法
-
ソケットでクライアントのipア...
-
VB6のwinsockでconnectできない
-
Connectエラーが出てしまう・・...
-
ソケット通信の送受信遅延-02 ...
-
同じLAN内パソコンのIPアドレス...
-
WinSockでの通信プログラムがう...
-
UDPのソケットプログラミング
-
非ブロッキングソケットのrecv...
おすすめ情報