0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Java】socketを用いたクライアント/サーバ間通信の基礎

Posted at

はじめに

表記の件の備忘録です。ネットワークと、スレッドについて学習したかったのでまとめました。

ソケットを用いた通信の手順

  1. サーバーでServerSocketを作成し、クライアントからの接続を待ち受ける
  2. クライアントがソケットを作成すると、サーバーとクライアントの間で接続が確立される
  3. サーバーが文字列を書き出し、それをクライアントが読み込む
  4. ソケットをクローズする

プログラム例

サーバ側を先に起動すること。

サーバ側プログラム
package com.example;

import java.io.BufferedWriter;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public final class Server {
    private Server() {
    }

    public static final int PORT = 10000;

    public static void main(String[] args) {
        try (ServerSocket serverSocket = new ServerSocket(PORT)) {
            System.out.println("待機します。");

            while (true) {
                Socket socket = serverSocket.accept(); // 接続を受け付ける
                System.out.println("ようこそ。");

                PrintWriter printWriter = new PrintWriter(
                        new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())));
                printWriter.println("こちらはサーバです。");
                printWriter.flush();
                printWriter.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
クライアント側プログラム
package com.example;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.Socket;

public class Client {
    public static final String HOST = "localhost"; // 接続先のホスト名
    public static final int PORT = 10000; // 接続先のポート番号

    public static void main(String[] args) {
        try (Socket socket = new Socket(HOST, PORT)) {
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));

            String str = bufferedReader.readLine();
            System.out.println(str);

            bufferedReader.close();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
サーバ側出力
$ java <プログラム実行のコマンド>
待機します。
ようこそ。
ようこそ。
クライアント側出力
$ java <プログラム実行のコマンド>
こちらはサーバです。
$ java <プログラム実行のコマンド>
こちらはサーバです。

スレッドも利用した通信

概要

Javaでは、スレッドはjava.lang.Threadクラスを使って作成する。スレッドを利用する方法は主に2つある。

  1. Threadクラスを拡張する
    Threadクラスを拡張して、自分のスレッドクラスを作成する。run()メソッドをオーバライドし、start()でスレッドを起動する。
  2. Runnableインターフェースを実装する
    Runnableインターフェースを実装して、Threadクラスに渡す。

プログラム例

サーバ側メインスレッド
public class Server {

    public static void main(String[] args) {
        ServerThread serverThread = new ServerThread();
        serverThread.start();

        while (true) {
            try {
                Thread.sleep(5000); // 5秒間スリープ
                System.out.println("サーバ側メインスレッドも起動中です。");
            } catch (InterruptedException e) {
                System.out.println("スリープが中断されました: " + e.getMessage());
            }
        }
    }
}
サーバ側通信用スレッド
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class ServerThread extends Thread {

    public static final int PORT = 10000;

    public ServerThread() {

    }

    public void run() {

        try (ServerSocket serverSocket = new ServerSocket(PORT)) {
            Socket socket = serverSocket.accept();

            try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                    PrintWriter printWriter = new PrintWriter(
                            new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())))) {

                String message;
                while ((message = bufferedReader.readLine()) != null) {
                    printWriter.println("サーバ:" + message + "受け付けました。");
                    printWriter.flush();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}
クライアント側メインスレッド
public class Client {

    // メインスレッドは、コンソールから入力を受け付け、サーバーに送信する
    public static void main(String[] args) {

        // サーバから受信を行うスレッドを立ち上げる
        Thread thread = new Thread(new ClientThread());
        thread.start();

        while (true) {
            try {
                Thread.sleep(3000);
                System.out.println("クライアント側メインスレッドも起動中です");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

}
クライアント側通信用スレッド
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;

public class ClientThread implements Runnable {

    public static final String HOST = "localhost";
    public static final int PORT = 10000;

    // サーバーからの文字列を受信し続け、コンソールに出力する
    public void run() {
        try (Socket socket = new Socket(HOST, PORT);
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                PrintWriter printWriter = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
                BufferedReader consoleReader = new BufferedReader(new InputStreamReader(System.in))) {

            System.out.println("サーバに接続しました。");
            String userInput;
            while (true) {
                System.out.print("サーバに送信するメッセージを入力してください。>");
                userInput = consoleReader.readLine();

                printWriter.println(userInput);
                printWriter.flush();

                String serverResponse = bufferedReader.readLine();
                System.out.println(serverResponse);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?