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

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

ただいまの
回答率

90.33%

  • Java

    14463questions

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

  • C#

    7742questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

  • Unity

    4451questions

    Unityは、ユニティテクノロジーが開発したゲームエンジンです。 主にモバイルやブラウザ向けのゲーム製作に利用されていましたが、3Dの重力付きゲームが簡単に作成できることから需要が増え、現在はマルチプラットフォームに対応しています。 言語はC言語/C++で書かれていますが、C#、JavaScript、Booで書かれたコードにも対応しています。

  • TCP

    170questions

    TCP(Transmission Control Protocol)とは、トランスポート層のプロトコルで、コネクション型のデータサービスです。

文字列の引き渡しがうまくいかない

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 190

kurofuku

score 1

 前提・実現したいこと

C#をクライアント、javaをサーバとしてUnityでTcpClient通信をしています。

アカウント登録時には、ユーザー名とパスワードをクライアントプログラム側(C#側)で受け付け、それをWriteLineを用いてサーバ側(java側)に受け渡し、サーバはそれをテキストデータとして保存するという作業を行っています。ユーザー名とパスワードはstring型で保管しています。

ログイン時にはサーバがテキストデータに保管しているユーザー名とクライアント側が入力したユーザ名とが一致していた場合trueを返し、ログイン成功になります。

 発生している問題・エラーメッセージ

問題はアカウント登録後に再ログインする際に発生しております。
ユーザー名を仮にuser、パスワードをpassとします。アカウント登録は問題なく行えており、サーバ側のテキストデータにもuser,passという風に保存できているのですが、ログインとなると、クライアント側はuser,passを正常にサーバに送れているにもかかわらずサーバが保管しているuserとクライアントが送ったuserが一致しません。エラーメッセージは「アカウントが存在しません」と出ます。一致するかの判定はequalsで行っています。

よろしくお願いします。

 該当のソースコード

using System.Collections;
using System.Collections.Generic;
using UnityEngine.SceneManagement;
using UnityEngine;
using UnityEngine.UI;
using System.Net;
using System.Net.Sockets;
using System.IO;

public class LoginManager : MonoBehaviour {


    NetworkStream ns;
    StreamReader sr;
    StreamWriter sw;

    public string flag = "false3";
    public GameObject buttonMessage;
    public GameObject buttonMessageText;


    string playername;
    private string password;
    public InputField nameinputField;
    public InputField passinputField;



    public AudioClip mainAudio;
    public static AudioSource audioSource;
    public bool DontDestroyEnabled = true;




    // Use this for initialization
    void Start()
    {


        ns = TitleManager.tc.GetStream();  //違うシーンでtcpをつなげているためストリームの宣言だけ
        sr = new StreamReader(ns);
        sw = new StreamWriter(ns);

        buttonMessage.SetActive(false); //警告ボタン非表示



    }

    // Update is called once per frame
    void Update()
    {

    }

    public void PushLoginButton()
    {



        playername = nameinputField.text;
        password = passinputField.text; 

        Debug.Log("プレイヤ名は(" + playername + ")");
        Debug.Log("パスワードは" + password);

        resetInputField();

        if (playername.Equals("") || password.Equals(""))
        {
            DisplayMessage("プレイヤ名またはパスワードを入力してください"); //何も入力されていないとき

        }
        else
        {
            sw.WriteLine("2");      //ログインかアカウント登録の判定。1はアカウント登録、2はログイン
            sw.WriteLine(playername);
            sw.WriteLine(password);     //サーバに送信

            sw.Flush();

            flag = GetData(sr);     //サーバからログイン判定の受付
            if (flag.Equals("false1"))      //playernameが存在しないとき
            {
                DisplayMessage("アカウントが存在しません");
            }
            else if (flag.Equals("false2"))     //playernameが存在するがpassが違うとき
            {
                DisplayMessage("パスワードが違います");
            }
            else if (flag.Equals("true"))       //ログイン成功
            {

                /*sr.Close();
                sw.Close();
                ns.Close();*/
                TitleManager.audioSource.Stop();

                audioSource = gameObject.GetComponent<AudioSource>();
                audioSource.clip = mainAudio;
                audioSource.Play();
                if (DontDestroyEnabled)
                {
                    // Sceneを遷移してもオブジェクトが消えないようにする
                    DontDestroyOnLoad(this);

                }

                SceneManager.LoadScene("MainScene");
            }
        }
    }

    public void PushAccountButton()
    {
        playername = nameinputField.text;
        password = passinputField.text;

        Debug.Log("プレイヤ名は" + playername);
        Debug.Log("パスワードは" + password);


        if (playername.Equals("") || password.Equals(""))
        {
            DisplayMessage("プレイヤ名またはパスワードを入力してください");

        }
        else
        {
            sw.WriteLine("1");
            sw.WriteLine(playername);
            sw.WriteLine(password);

            sw.Flush();

            flag = GetData(sr);
            if (flag.Equals("false"))
            {
                DisplayMessage("既に登録されているアカウント名です");
            }
            else if (flag.Equals("true"))
            {
                /*sr.Close();
                sw.Close();
                ns.Close();*/

                TitleManager.audioSource.Stop();
                audioSource = gameObject.GetComponent<AudioSource>();
                audioSource.clip = mainAudio;
                audioSource.Play();
                if (DontDestroyEnabled)
                {
                    // Sceneを遷移してもオブジェクトが消えないようにする
                    DontDestroyOnLoad(this);

                }

                SceneManager.LoadScene("MainScene");
            }
        }


        //SceneManager.LoadScene("AccountScene");
    }

    void resetInputField()
    {
        nameinputField.text = "";

        passinputField.text = "";


    }

    public void DisplayMessage(string str)
    {
        buttonMessage.SetActive(true);
        buttonMessageText.GetComponent<Text>().text = str;
    }

    public void PushButtonMessage()
    {
        buttonMessage.SetActive(false);
    }

    string GetData(StreamReader sr)//データ読み取り用メソッド
    {
        string gotdata = null;
        do
        {
            gotdata = sr.ReadLine();//入力ストリームから読み取り

        } while (gotdata == null);

        return gotdata;
    }


}
public boolean checkData(String name, String password, int playerNo) {
        try {

            FileReader fr = new FileReader("PlayerData.txt");
            BufferedReader br = new BufferedReader(fr); //入力ファイルオープン
            String gotline, getst, getname;
            StringTokenizer st;


            System.out.println("checkData("+name+","+password+","+playerNo+")"); //サーバ確認
            while((gotline=br.readLine()) != null) {
                st = new StringTokenizer(gotline,",{=}");
                getst = st.nextToken();

                System.out.println(name.equals(getst));
                getname = new String(name);

                //名前が一致したら
                if(name.equals(getst)) {
                    br.close();

                    //パスワードが一致したら
                    if((st.nextToken()).equals(password)) {
                        playerdata[playerNo] = new PlayerData();
                        //playerdata[playerNo].title = new String[16][2];

                        playerdata[playerNo].name = name; //名前格納
                        playerdata[playerNo].password = password; //パスワード格納

                        //TODO 進行度、それぞれの章の金額をクライアントに送信

                        pw[playerNo].println("true");//クライアントに成功通知
                        pw[playerNo].flush();
                        System.out.println("アカウント確認 : 成功"); //サーバ確認
                        br.close();
                        return true;
                    }else {
                        pw[playerNo].println("false2");//クライアントに失敗通知
                        pw[playerNo].flush();
                        System.out.println("アカウント確認 : 失敗(パスワード不一致)"); //サーバ確認
                        br.close();
                        return false;
                    }
                }
            }

            pw[playerNo].println("false1");//クライアントに失敗通知
            pw[playerNo].flush();
            System.out.println("アカウント確認 : 失敗(名前不一致)"); //サーバ確認
            br.close();
        }catch(IOException e) {
                e.printStackTrace();
        }
        return false;
    }





    //アカウントの登録
    public boolean makeData(String name, String password, int playerNo) {
        try {
            System.out.println("makeData("+playerNo+")"); //サーバ確認

            FileReader fr = new FileReader("PlayerData.txt");
            BufferedReader br = new BufferedReader(fr); //ファイルオープン
            String gotline;
            StringTokenizer st;

            //保存ファイルの読み込み開始
            while((gotline=br.readLine()) != null) {
                st = new StringTokenizer(gotline,",");
                //名前があったら
                if(st.hasMoreTokens()){
                    if((st.nextToken()).equals(name)) {
                        pw[playerNo].println("false");//クライアントに失敗通知
                        System.out.println("アカウント登録 : 失敗(名前被り)");
                        br.close();
                        return false;
                    }
                }
            }
            br.close();

            FileWriter fw = new FileWriter("PlayerData.txt", true);
            BufferedWriter bw = new BufferedWriter(fw); //出力ファイルオープン

            bw.write(name+","+password+","+"仮データ1"+","+"仮データ2\n"); //保存ファイルに書き込み(仮)
            pw[playerNo].println("true");//クライアントに成功通知
            System.out.println("アカウント登録 : 成功");
            bw.close();
        }catch(IOException e) {
            e.printStackTrace();
        }
        return true;
    }

 試したこと

テキストデータの一行目のplayernameは認識されないのですが、二行目以降は認識され、ちゃんとログインできることが確認できました。なぜ一行目だけちゃんと認識されないのでしょうか?

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

「テキストデータの一行目のplayernameは認識されない」という点から、BOMが付いていませんか?
本来の文字数と取得した文字数を比較して3文字多いなら多分そうだと思うので、
TXTをBOM無しで保存するか該当文字列の先頭3文字を削れば動くのではないかと。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/07/13 13:37

    テキストデータをUTF-8NにしてBOMなしで保存してみたら一行目が認識されました!
    どうやらWindowsのメモ帳をテキストデータとして利用すると必ずBOM付きで保存されてしまうみたいですね。頭にBOMがついていたことによる誤認識でした。
    ご回答ありがとうございました!

    キャンセル

同じタグがついた質問を見る

  • Java

    14463questions

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

  • C#

    7742questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

  • Unity

    4451questions

    Unityは、ユニティテクノロジーが開発したゲームエンジンです。 主にモバイルやブラウザ向けのゲーム製作に利用されていましたが、3Dの重力付きゲームが簡単に作成できることから需要が増え、現在はマルチプラットフォームに対応しています。 言語はC言語/C++で書かれていますが、C#、JavaScript、Booで書かれたコードにも対応しています。

  • TCP

    170questions

    TCP(Transmission Control Protocol)とは、トランスポート層のプロトコルで、コネクション型のデータサービスです。