java.net.ServerSocket
このクラスを使用してサーバーを作成します。
サーバー側のコードは以下の通りになります。
ちなみに通信がまともに繋がるまで、テストした時の残骸が残っております。
サーバー
/**
* サーバーソケットクラス。
* コンストラクタで指定されたポート番号でサーバーを起動します。<br/>
* ローカルホスト(アプリを起動するPC)上の指定ポート番号で受付を開始します。
* @author takunoji
* 2019/07/20
*/
public class SocketServerBasic {
private ServerSocket server;
/**
* コンストラクタ。
*
* @param portNo アクセスを受け付けるポート番号
*/
public SocketServerBasic(int portNo) {
try {
server = new ServerSocket(portNo);
if (server.isBound() == false) {
server.bind(new InetSocketAddress("localhost", portNo));
server.setSoTimeout(3000);
}
} catch (IOException e) {
this.finalize();
e.printStackTrace();
}
}
/**
* Objectクラスの終了処理(ガベージコレクションに呼ばれる)
*/
@Override
public void finalize() {
// メモリの解放
server = null;
}
/**
* コンストラクタで作成されたサーバーソケットで
* 受付処理を開始する。
*/
public void startServer() {
try {
System.out.println("*** SocketServer start " + server.isBound() + "***");
Socket recieve = server.accept();
System.out.println("*** Server Get Request start***");
// 受信データの読み込み
StringBuilder responseTxt = new StringBuilder("<Response>");
// 受信状態
System.out.println("クライアント: " + recieve.getRemoteSocketAddress());
System.out.println("接続: " + recieve.isConnected());
System.out.println("入力ストリームが閉じている: " + recieve.isInputShutdown());
// 受信したリクエスト
InputStream in = recieve.getInputStream();
// 返却するレスポンス
OutputStream writer = recieve.getOutputStream();
System.out.print("Server recieve is ...");
int c = 0;
// CRとCRLFの場合で入力が終了している時がある
while((c = in.read()) != -1) {
char ch = (char)c;
responseTxt.append(ch);
// 空の場合
if (c == 10 || c == 13) {
break;
}
}
System.out.println(responseTxt.toString());
System.out.println("*** Server Send Response start***");
// レスポンス送信
writer.write((responseTxt.toString() + System.getProperty("file.separator")).getBytes());
writer.flush();
in.close();
writer.close();
System.out.println("*** SocketServer end ***");
} catch (IOException e) {
e.printStackTrace();
} finally {
// 開いたストリームを閉じる
try {
closeServer();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* ソケットサーバーを終了します。
*/
public void closeServer() throws IOException {
server.close();
server = null;
}
/**
* メインメソッド
* @param args プログラム引数
*/
public static void main(String[] args) {
SocketServerBasic serverSocket = new SocketServerBasic(8080);
serverSocket.startServer();
}
}
クライアント
public class ClientSocketBasic {
private static final String HOST = "localhost";
private static final int PORT = 8080;
/**
* コンストラクタ
* @param portNo ポート番号
*/
public static void main(String[] args) {
System.out.println("*** SocketClient start ***");
try (Socket sock = new Socket(HOST, PORT)) {
// 受信したレスポンス
InputStream reader = sock.getInputStream();
// 送信するリクエスト
OutputStream writer = sock.getOutputStream();
System.out.println("接続済み: " + sock.isConnected());
System.out.println("接続サーバー: " + sock.getRemoteSocketAddress());
// リクエスト送信
writer.write("ping...\n".getBytes());
writer.flush();
System.out.println("*** Testing start " + sock.getInetAddress() + " ***");
// レスポンス受信
int c = 0;
while((c = reader.read()) != -1) {
System.out.print((char)c);
}
System.out.println("*** Testing end***");
// 終了処理
reader.close();
writer.close();
sock.close();
System.out.println("*** SocketClient end ***");
} catch (IOException e) {
e.printStackTrace();
}
}
}
ハマったところ
ここで自分が詰まったのはクライアントからのデータを受信するときに「BufferedReader#readLine()]」を使用していたところです。
原因は。。。
データを送信するときに改行がないと受信時にデータの終わりが確認できないので「readLine()」のところで処理が止まってしまうところです。
とりあえずはこちらを参照して実装しました。
実装してみたところ、サーバーとクライアントの送受信で互いに「読み取り」処理の時の区切りが悪かった。。。なので下のように、送信データの終わりが明確にわかるように実装しました。
int c = -; while((c = reader.read()) != -1) { char ch = (char) c; stBuilder.append(ch); }
こんな感じで実装していたのですが、読み取るデータがいつになっても「-1」にならない事件が起きてしまい。。。
結局は下のようにコードを直しました。
int c = -; while((c = reader.read()) != -1) { char ch = (char) c; stBuilder.append(ch); if(c == 10 || c == 13) { break; } }
c == 10, 13の部分はchar型のint値です。10はLF(改行文字)で13はCR('改行文字)のようです。参考サイト
ソースコードはGitにアップしています。SocketServerBasic.java, ClientSocketBasic.javaをアップしてあります。
ネットワーク確認コマンド
コマンドプロンプトで下のようなコマンドを叩くと、使用しているポートがわかります。以下コマンドの書き方
netstat -nao | find "[ポート番号]"
netstat -a(使用している全ポートを一覧)
勘違いによるエラー
1.接続ポートを間違える
あたりまえだけど、サーバーがlocalhost: 2000で動いているならば、クライアントはlocalhost: 2000に接続する必要があります。「java.net.ConnectException」が出力されます。
2.テストしたときのコネクションが残っている
実装時に処理の起動確認を行いながらやりますが、処理の実行時にコネクションが消えていない、となると「Address already in use」とかエラーが出ます。
3.クライアントからの送信するデータの終わり
クライアントからサーバーへデータを送信するデータの終わりを示す文字として「改行コード」を入れてやる必要がある。でないといつまでもサーバーが受信待機する。
とりあえず完了
いやー、read()処理の部分でハマりました(笑)
昔はreadLine()とかで問題なく動いたのですが、ちょっと変わっているようです。今回の実装はJDK1.8での実装になります。
でわでわ。。。
やったこと一覧
- Eclipse+Gluonでスマホアプリを作る
- Micro:bitで遊ぶ
- Eclipseのセットアップ: 再生リスト
- LWJGL〜GitBook Chapter1-7〜
- IntelliJ IDEA〜セットアップなど〜
- Java Coord〜Java + Discord〜
- Java Basic〜Javaの基本〜: 再生リスト
- JavaDoc〜JavaDocの解釈〜
- ラズパイ(RPi)関連〜RPiで遊んでみる〜
- JavaミニGame〜Java Console Game〜
- Eclipseアプリ作成〜家計簿アプリ作成〜
- OpenCv〜環境構築〜
- OoenCV + JavaFX
- JavaFXでハローワールド〜OpenCVチュートリアル迄〜
- Git操作〜Git関連〜
- JUnit〜Javaで遊ぶならこれ!〜
- TensorFlow〜Kerasで機械学習〜
ワンポイントレッスン的な
- JavaFX SceneBuilder〜ボタンにメソッドを割り当てるワンポイント〜
- JavaFX LineChart 〜グラフを描く、ワンポイントレッスン的な〜
- ND4J ベクトル生成〜ワンポイントレッスン的な〜
Micro:bitで遊ぶ
- Micro:bit(Chibi:bit) での開発環境セットアップ
- Micro:bit スマホでプログラミング〜ブラウザにアクセス〜
- Micro:bit スマホでプログラミング〜Bluetoothの設定〜
- PHP JS 〜WebSocketもどきの作成〜
- PHP ServerSocket 〜レンタルサーバーでSocket受信〜
- Python websocket client〜WebSocket送信処理を作る〜
- Micro:bit Python 〜マイクロビット→PCへシリアル通信〜
- ターミナル(コマンド)を使う 〜FTPSを使ってファイルアップロード〜
- Microbit リファレンス 〜サイトを眺めてみる〜
- Microbitで遊んでみる
- Microbitで遊ぶ〜ボタンを押す〜
- Microbitで遊ぶ〜シリアル通信をする〜
- Java Microbit Serial data connect 〜シリアル通信〜※中途半端です
- Microbit Python 〜シリアル通信データを受け取る〜
- Microbit Python HTTP リクエストを飛ばす
- Microbit花火〜MicrobitからWebServerまでの旅〜
Eclipse セットアップ
- Java Install Eclipse〜開発ツールのインストール〜
- TensorFlow C++環境〜EclipseにCDTをインストール〜
- Setup OpenGL with Java〜JOGLを使う準備 for Eclipse〜
- Eclipse Meven 開発手順〜プロジェクトの作成〜
- Java OpenCV 環境セットアップ(on Mac)
- Eclipse SceneBuilderを追加する
- JavaFX SceneBuilder 〜EclipseとSceneBuilder連携~
Eclipse+Gluon(MobileApp)
- Eclipse Android〜Gluonでアプリを作る〜
- Eclipse Android〜Gluonでアプリを作る2〜
- Eclipse Android〜Gluonでアプリを作る3: 3Dモデル〜
- Eclipse Android〜Gluonでアプリを作る4: 普通に作る〜
- Eclipse Android〜Gluonでアプリを作る5: ゲーム部分を作る〜
LWJGL
- Chapter1[外枠の表示のみ]
- Chapter2-1〜クラスの構成〜
- Chapter2-2〜インターフェースの使い方と詳細〜
- Chapter2-3〜GameEngineクラス(サンプルクラス)〜/li>
- Chapter2-4〜Windowクラス(サンプルクラス)〜
- Chapter3〜描画処理を読む〜
- Chapter4〜シェーダについて〜
- Chapter5-1〜レンダリングについて〜
- Chapter5-2〜レンダリング詳細〜
- Chapter6〜Projection(投影)〜
- Chapter7-1〜Cubeを作る〜
- Chapter7-2〜Texture〜
- Java 3DGame LWJGL Retry Lv1 〜動かして理解する〜
- Java 3DGame LWJGL Retry Lv2 〜動かして理解する2〜
- Java 3DGame LWJGL Retry Lv3 Texture〜動かして理解する3〜「負け越し」
- Java 3DGame LWJGL Retry Lv4 デバック〜動かして理解する4〜「黒星」
- Java 3DGame LWJGL Retry Lv5 遊んでみる〜動かして理解する5〜「引分け」
- Java 3DGame LWJGL Retry Lv6 遊んでみる2〜動かして理解する6〜「白星」
- ava 3DGame LWJGL Retry Lv7 遊んでみる3〜全部テクスチャにする〜
IntelliJ IDEA
- IntelliJ IDEA 環境構築 〜インストールと起動〜
- IntelliJ IDEA Git〜Gitリポジトリからクローン〜
- IntelliJ IDEA 使い方〜Git接続 Java起動 etc〜
- IntelliJ IDEA Jarファイルを作る
- IntelliJ IDEA 使い方〜Maven Projectの作成〜
- IntelliJ IDEA 使い方〜Mavenでライブラリを追加する〜
- IntelliJ IDEA 使い方〜Javaのコンパイルレベル設定〜
- IntelliJ IDEA Gradleセットアップ〜コマンド入力部の表示〜
- IntelliJ IDEA Discord Botを作る〜Gradle環境のセットアップ〜
Java Discord
- IntelliJ IDEA Discord Botを作る〜Gradle環境のセットアップ〜
- Java Discord セットアップ〜Hello Discord〜
- Java Discord ピンポン〜Discordプログラム〜
- Java Discord Listener実装〜コマンドを好きなだけ追加しよう〜
Java Basic
- Java Basic Level 1 〜Hello Java〜
- Java Basic Level2 〜Arithmetic Calculate〜
- Java Basic Level3 〜About String class〜
- Java Basic Level 4〜Boolean〜
- Java Basic Level 5〜If Statement〜
- Java Basic Summary from Level1 to 5
- Java Basic Level 6 〜Traning of If statement〜
- Java Basic Level8 〜How to use for statement〜
- Java Basic Level 8.5 〜Array〜
- Java Basic Level 9〜Training of for statement〜
- Java Basic Level 10 〜While statement 〜
- Java Basic Swing〜オブジェクト指向〜
- Java Basic Swing Level 2〜オブジェクト指向2〜
- サンプル実装〜コンソールゲーム〜
- Java Basic インターフェース・抽象クラスの作り方
- Java Basic クラスとは〜Step2_1〜
- Java Basic JUnit 〜テストスイートの作り方〜
JavaDoc
- Java Doc 読解 System
- Java Doc 読解〜System.out〜
- Java Doc読解 〜System.In〜
- JavaDoc 読解 〜 Filesクラス 〜
- Java Doc読解 BufferedReader
- Java Doc 読解〜BufferedWriter〜
- Java Doc 読解 List 〜JavaDocList その1〜
- Java Doc 読解 Map
- Java Doc Classloader
ラズパイ(RPi)関連
- ラズパイ SSH接続メモ
- ラズパイ Under-voltage detected! 〜エラー対処〜
- ラズパイ(CUI)セットアップ
- RPi Settingup Wifi in CUI ~ラズパイ CUI Wifi接続~
- Memos about Settingup RPi ~使用したコマンドメモ~
- RPi and JavaFX sample of deployment 〜ラズパイにサンプルデプロイ〜
- RPi JavaFX execution ~ラズパイ JavaFX自動起動~
- RPi Install Git 〜ラズパイにGitのインストール〜
- RPi Java Swing〜ラズパイにJava Swingアプリを起動する〜※失敗しています。。。」
- RPi Maven Install 〜ラズパイでMeven〜
- Install XFCE4 on RPi 〜ラズパイに高速軽量デスクトップインストール〜
<Java Step1〜ミニゲーム作成>
- Java Hello World はじめのプログラム 〜 Step1-1〜
- Java 四則演算 演算子 〜Step1-2〜
- Java データ型 変数の扱い方〜Step1-2-1〜
- Java Basic Booleanなどの意味 〜Step1_2_2〜
- Java Basic for文 〜Step1_3_1〜
- Java Basic While文 〜 Step1_3_2〜
- Java Basic try catch文 〜Step1_3_3〜
- Java Basic クラスとは〜Step2_1〜
- Java Basic API Listの使い方 〜Step2_2〜
- Java Basic インターフェース 〜Step2_3 〜
- Java Basic ミニゲーム作成 〜Step3_1〜
- Java Basic ミニゲーム作成 〜Step3_2〜
家計簿アプリ作成
- Eclipse アプリ作成 Lv1〜家計簿を作る準備〜
- Eclipse アプリ作成 Lv2〜家計簿を作る土台作り〜
- Eclipse アプリ作成 Lv3〜3Dグラフ用Cube作り〜
- Eclipse アプリ作成 Lv4〜3Dグラフ用Cubeに高さを与える〜
- Eclipse アプリ作成 Lv5〜惨敗:CubeにTextureを貼る〜
- Eclipse アプリ作成 Lv7〜Cubeを日付順に並べる〜
Git
- Java Git clone in Eclipse 〜サンプルの取得〜
- Eclipse Gitリポジトリの取得 〜GitからソースをPullしよう〜
- IntelliJ IDEA Git〜Gitリポジトリからクローン〜
OpenCv
- Java OpenCV 環境セットアップ(on Mac)
- Java OpenCv Lv1 〜入門: 写真の表示〜
- Java OpenCV Lv2 〜画像を表示する〜
- Java OpenCV Lv3 〜画像の平滑化(smooth())〜
- Java OpenCV Lv3 〜画像にガウシアンフィルタ(GaussianBlur())〜
- Java OpenCV Lv3 〜画像に中央値フィルタ(medianBlur())〜
- Java OpenCV Lv4 〜画像の中身をみてみる〜
- Java OpenCV Lv5 〜Matクラスで描画処理〜
- Java OpenCV Lv6 〜Matクラスで背景から作成してみる〜
- Java OpenCV Lv7 〜MatクラスでEllipseしてみる〜
- Java OpenCV Lv9 〜画像編集「足し算」(cvAdd)〜
- Java OpenCV Lv9 〜画像編集「引き算」(cvSubtract)〜
- Java OpenCV Lv9 〜画像の掛け算〜
- Java OpenCV Lv10 〜行列演算Mat#submat()〜
- Java OpenCv Lv10〜画像の平均値をだす〜
OpenCv + JavaFX
- EclipseにSceneBuilderを追加する
- JavaFX SceneBuilder 〜EclipseとSceneBuilder連携~
- Java OpenCv Lv1 〜入門: 写真の表示〜
- Java OpenCV Lv2 〜JavaFXでの画像表示〜
- Java OpenCv ビデオキャプチャ〜カメラからの入力を表示〜
- OpenCV tutorial〜ヒストグラム〜
- OpenCV tutorial 解析 〜ヒストグラム〜
- OpenCV tutorial 解析2 〜ヒストグラム計算〜
- OpenCV tutorial 〜フーリエ変換など〜
JavaFXでハローワールド〜OpenCVまで
- Java 初めてでも大丈夫〜ステップアッププログラミングのススメ〜
- ステップアッププログラミング〜Java FxでHelloWorld解説〜
- Java StepUpPrograming〜JavaFX で四則計算〜
- Java StepUpPrograming〜JavaFXで画面切り替えを作る1〜
- Java StepUpPrograming〜JavaFXで画面切り替え2ボタン作成〜
- Java StepUpPrograming〜JavaFXで画面切り替え3アクション〜
- Java StepUpPrograming〜JavaFXで画面切り替え4Pane切り替え〜
- Java StepUpPrograming〜JavaFXで画面切り替え5WebEngine〜
JavaFX + ND4Jで機械学習準備
- JavaFX + ND4J〜数学への挑戦1:ND4Jのインストール〜
- JavaFX + ND4J〜数学への挑戦2: 行列の計算〜
- Java + ND4J 〜数学への挑戦3: ベクトル(配列)の作成方法〜
- ND4J ベクトル生成〜ワンポイントレッスン的な〜
- JavaFX + ND4J 〜数学への挑戦:5グラフを描く〜
- JavaFX + ND4J 〜グラフ作成の準備〜
- JavaFX + ND4J 〜グラフ作成:とりあえず表示〜
- JavaFX グラフ描画〜AreaChartを使う〜
- JavaFX + ND4J〜数学への挑戦6:グラフの土台を作る〜
JUnit関連
TensorFLowを学ぶ
- Tensorflow Keras 〜初めてのKeras〜
- Tensorflow Keras Errors〜”python is not installed as a framework.”〜
- Python Tensorflow 〜初めての人工知能(TensorFlowインストール)〜
- Tensorflow Keras〜初めのトレーニング_1〜
- Tensorflow Keras〜初めのトレーニング_2:前処理〜
- TensorFlow Keras〜テキストの分類〜
- Python TensorFlow tutorial〜チュートリアルを進めるコツ、ワンポイント〜
- TensorFlow Keras〜回帰、準備から予測まで〜
- TensorFlow Java 環境構築〜JavaでもTensorFlow〜
[rakuten ids="soukai:10640969"]