質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

ソケット

TCP/IPにおいて、IPアドレスとサブアドレスであるポート番号を組み合わせたネットワークアドレスのことを呼びます。また、ソフトウェアアプリケーションにおいて、TCP/IP通信を行う為の仮想的なインターフェースという意味もある。

Q&A

解決済

1回答

12126閲覧

java.net.SocketExceptionの対処法

akaevaka

総合スコア8

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

ソケット

TCP/IPにおいて、IPアドレスとサブアドレスであるポート番号を組み合わせたネットワークアドレスのことを呼びます。また、ソフトウェアアプリケーションにおいて、TCP/IP通信を行う為の仮想的なインターフェースという意味もある。

0グッド

0クリップ

投稿2021/06/28 13:44

編集2021/06/29 06:07

###質問内容
ソケットを使って,
名前,スコア,モード(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がしっかりと待機するようにするにはどうすればよいですか
文字数の都合上,必要ないと判断した関数は省略しました

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

クライアントが readLine する前にサーバの方が先にコネクションを切断しているのでは?

投稿2021/06/28 23:26

sigsegv

総合スコア895

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

akaevaka

2021/06/29 05:29

追記のほうにサーバー側の動きを載せたのですが,最後にcloseしているのでreadLineする前にコネクションを切断していない,と考えていたのですが,なにか順番がおかしいのでしょうか.
akaevaka

2021/06/29 12:30

thread.sleepをいれて時間遅らせたら問題なくいけました
sigsegv

2021/06/29 14:52

すでに質問が解決済みになりましたが、一応気になった点を。 サーバ側の最後に s.close() をしていますが、クライアントと通信しているソケットは socket なので、socket .close() も入れたほうがいいと思います。
akaevaka

2021/06/30 02:01

ご指摘ありがとうございます,そのようにさせていただきます. ありがとうございました.
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問