###質問内容
ソケットを使って,
名前,スコア,モード(easyかhardを数字で表したものの文字列)
をサーバーに送信しようと考えています.
ですが,実行しようとしてみたところ,Requester.sendScoreのshow ranking とコメントしたループのin.readLineが原因でjava.net.SocketException: Connection resetという例外が出てしまいました.
これはどのようにすれば解消できますか.
リンク内容
うえのようなサイトを見たところ範囲が広い例外のようで.調べてもあまり良くわかりませんでした.
###Requester
Java
1import java.net.*; 2import java.util.*; 3import java.io.*; 4 5public class Requester extends Worker { 6 //send score to server, show ranking 7 public void sendScore(Player player){ 8 try { 9 String name = player.getName(); 10 String score = String.valueOf(player.getScore()); 11 String mode = String.valueOf(player.getMode()); 12 13 InetAddress addr = InetAddress.getByName("localhost"); // change for IP address 14 Socket socket = new Socket(addr, 8080); //set port No. 15 PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true); 16 out.println(name); //send name 17 out.println(score); //send score 18 out.println(mode); //send mode 19 20 BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); 21 22 //show ranking 23 for(int i=0; i<6; i++){ 24 String str = in.readLine(); 25 System.out.println(str); 26 Thread.sleep(1000); 27 } 28 29 socket.close(); 30 } catch (Exception e) { 31 e.printStackTrace(); 32 } 33 } 34 35}
###例外本文
java.net.SocketException: Connection reset at java.base/sun.nio.ch.NioSocketImpl.implRead(NioSocketImpl.java:323) at java.base/sun.nio.ch.NioSocketImpl.read(NioSocketImpl.java:350) at java.base/sun.nio.ch.NioSocketImpl$1.read(NioSocketImpl.java:803) at java.base/java.net.Socket$SocketInputStream.read(Socket.java:976) at java.base/sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:297) at java.base/sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:339) at java.base/sun.nio.cs.StreamDecoder.read(StreamDecoder.java:188) at java.base/java.io.InputStreamReader.read(InputStreamReader.java:178) at java.base/java.io.BufferedReader.fill(BufferedReader.java:161) at java.base/java.io.BufferedReader.readLine(BufferedReader.java:329) at java.base/java.io.BufferedReader.readLine(BufferedReader.java:396) at Requester.sendScore(Requester.java:55) at ClientMain.main(ClientMain.java:57)
###追記
Server側
updateRankingでスコアを受け取っています.
Java
1import java.net.*; 2import java.util.*; 3import java.util.Map.Entry; 4import java.io.*; 5 6 7public class Responser{ 8 private static ArrayList<String> Qstring = new ArrayList<>(); //question 9 private static ArrayList<Long> timeList = new ArrayList<>(); //waiting list 10 11 //accept score and register it to ranking 12 public void updateRanking() throws IOException { 13 ServerSocket s = new ServerSocket(8080); // make socket 14 Socket socket = s.accept(); // wait setting demand of connection 15 BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); 16 String p_name = in.readLine(); //accept name 17 String p_score = in.readLine(); //accept score 18 int p_mode = Integer.parseInt(in.readLine()); //accept mode 19 20 String rankingFilePath; 21 if(p_mode == 1) rankingFilePath = "data/ranking/easyranking.txt"; 22 else rankingFilePath = "data/ranking/hardranking.txt"; 23 24 //key=ID, value=score 25 Map<Integer,Integer> scores = new HashMap<Integer,Integer>(); 26 ArrayList<String> playerNameList = new ArrayList<String>(); 27 28 Scanner s2 = new Scanner(new File(rankingFilePath)); 29 int count = 1; 30 31 int id = -1, score = -1; 32 String name = ""; 33 while (s2.hasNext()){ 34 if(count % 3 == 1){ 35 id = Integer.parseInt(s2.next()); 36 }else if(count % 3 == 2){ 37 score = Integer.parseInt(s2.next()); 38 }else{ 39 name = s2.next(); 40 scores.put(id,score); 41 playerNameList.add(name); 42 } 43 count++; 44 } 45 46 try{ 47 int nextId = playerNameList.size()+1; 48 File file = new File(rankingFilePath); 49 FileWriter filewriter = new FileWriter(file, true); 50 filewriter.write(nextId + " " + p_score + " " + p_name + "\n"); 51 filewriter.close(); 52 scores.put(nextId, Integer.parseInt(p_score)); 53 playerNameList.add(p_name); 54 }catch(IOException e){ 55 System.out.println(e); 56 } 57 58 // make entry list of scorelist 59 List<Entry<Integer, Integer>> list_entries = new ArrayList<Entry<Integer, Integer>>(scores.entrySet()); 60 61 //sort scorelist 62 Collections.sort(list_entries, new Comparator<Entry<Integer, Integer>>() { 63 public int compare(Entry<Integer, Integer> obj1, Entry<Integer, Integer> obj2) { 64 return obj2.getValue().compareTo(obj1.getValue()); 65 } 66 }); 67 68 69 PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true); //setting of sending buffer 70 71 //send ranking data to client 72 String[] ordinalNumber = {"1st", "2nd", "3rd", "4th", "5th"}; 73 out.println("--- Rank | Player | Score ---"); 74 for(int i=0; i<5; i++){ 75 out.println(ordinalNumber[i] + ", " + playerNameList.get(list_entries.get(i).getKey()-1) + ", " + list_entries.get(i).getValue()); 76 } 77 s.close(); 78 } 79 80}
###ClientMain
Java
1import java.io.*; 2import java.util.*; 3 4public class ClientMain { 5 public static void main(String[] args) throws InterruptedException{ 6 Player player = new Player("", 0, 0); //(name, score, mdoe) 7 GameData gameData = new GameData(player); 8 ClientSystem clientsystem = new ClientSystem(); 9 Requester requester = new Requester(); 10 11 clientsystem.opening(); //op 12 13 clientsystem.say("Choose difficulty from easy:1 or hard:2."); 14 clientsystem.say("Input the difficulty number."); 15 Scanner scan = new Scanner(System.in); 16 int difficulty = scan.nextInt(); 17 18 player.setMode(difficulty); 19 requester.sendDifficulty(player); 20 21 clientsystem.say("send difficulty"); 22 clientsystem.say("gamedata download..."); 23 Thread.sleep(1000); 24 25 requester.requestGameData(gameData); //download gamedata from server 26 clientsystem.say("Load Successes!"); 27 Thread.sleep(2000); 28 29 clientsystem.startGame(gameData); //gamestart 30 System.out.println(); 31 clientsystem.say("Finish"); 32 33 clientsystem.showScore(player); //show score 34 35 36 clientsystem.say("Please input your name."); 37 38 String playerName = scan.nextLine(); 39 scan.close(); 40 player.setName(playerName); 41 42 requester.sendScore(player); 43 44 clientsystem.say("See you!"); 45 } 46}
###実行本文
[Welcome to this TYPING GAME.] [When this system says something, uses [] like this message] [--rule--] [Type the message enclosed in {}.] [The next is a example.] Q.{ もんだいぶん } [if you misstype and enter without modifying, subtract your score.] [There are two difficulty levels] [Choose difficulty from easy:1 or hard:2.] [Input the difficulty number.] 1 [send difficulty] [gamedata download...] [Load Successes!] [Are you ready?] [START!] 0 [Finish] [Score: 0] [Please input your name.] --- Rank | Player | Score --- java.net.SocketException: Connection reset すでに載せたので文字数の都合上割愛 [See you!] PS C:\Users\Client>
###原因の推定
名前の入力をまたずに
--- Rank |
というものが出力されてしまっているので,
名前の入力をしようとしたときにupdateRankingがもう始まってしまっているのが原因だと考えられます.
本来ならこのupdateはsendScoreを待たなければいけないのに先に終わらせてしまっているからこのような例がでたと考えております.
updateRankinggがしっかりと待機するようにするにはどうすればよいですか
文字数の都合上,必要ないと判断した関数は省略しました
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/06/29 05:29
2021/06/29 12:30
2021/06/29 14:52
2021/06/30 02:01