Javaを用いたソケット通信　前編

# *diff

[GitHub](https://github.com/jAkatsubaki/SocketApplicationWithKotlin)のコードをKotlin仕様に変更しました．
`jar`ふぁいる作成してクライアントとサーバでやり取りが可能です．

# Introduction

現在，Javaを用いた通信プログラムを作成しています．
しかし，OSIモデルや計算機の知識も乏しい僕にとっては，様々なドキュメントを読んでも理解しきれない部分が多いです．そこで今回は，ソケットプログラミングの仕組みをソースコード通して考えていこうと思います．間違っている部分もあると思うので，そこはご了承ください...

# What is Socket?

そもそもソケット（socket）とは

>ソケットとは，受け口、軸受け、接合部、穴、へこみなどの意味
>[e-words](http://e-words.jp/w/%E3%82%BD%E3%82%B1%E3%83%83%E3%83%88.html)

です．要するにネットワーク通信におけるソケットとは**サーバー/クライアント**が用意するデータの窓口のようなものなのです．

アプリケーションが通信するためには，IPアドレス（住所）とTCPポート（番地）が基本的に必要となります．ソケット通信では，ある特定の住所＋番地へ向かう道を作ってくれるのです．

# How can we implment in server?

では実際のソースコードを見ていきましょう．
サーバー側でソケット通信を開始するためには，以下のコードで手っ取り早く試験できます．

- ポートを設定
- ServerSocket インスタンスを作成
- Threadの継承クラスを作成しメソッドrun()を実行


```java:server.java
import java.io.*;
import java.net.*; //ServerSocket Class are defined
import java.util.*;

public class sample_server2
{
	//PORT Number
	public static final int PORT = 10000; //待ち受けポート番号

	public static void main(String[] args)
	{
		sample_server2 sm = new sample_server2();

		try{
			ServerSocket ss = new ServerSocket(PORT);

			System.out.println("Waiting now ...");
			while(true){
				try{
                    //サーバー側ソケット作成
					Socket sc = ss.accept();
					System.out.println("Welcom!");

					ConnectToClient cc= new ConnectToClient (sc);
					cc.start();
				}
				catch(Exception ex)
				{
					ex.printStackTrace();
					break;
				}
			}
		}
		catch(Exception e){
			e.printStackTrace();
		}
	}
}

//java.lang Package
class ConnectToClient extends Thread
{
	private Socket sc;
	private BufferedReader br;
	private PrintWriter pw;

    //コンストラクタ
	public Client(Socket s)
	{
		sc = s;
	}

    //スレッド実行
	public void run()
	{
		try{
            //クライアントから送られてきたデータを一時保存するバッファ（受信バッファ）
			br = new BufferedReader(new InputStreamReader(sc.getInputStream()));
            //サーバがクライアントへ送るデータを一時保存するバッファ（送信バッファ）
			pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(sc.getOutputStream())));
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}

		while(true){
			try{
                //受信バッファからデータを読み込む（今回は文字列）
				String str = br.readLine();
				System.out.println(str);
				Random rnd = new Random();
				RamdomStrings rs = new RamdomStrings();
                //クライアントからのメッセージの語尾＋ランダムな文字配列を送信バッファへ渡す
				pw.println("Server : [" + str.charAt(str.length()-1) + rs.GetRandomString(rnd.nextInt(10)) + "] (^_^)!");
                //ここが重要！flushメソッドを呼ぶことでソケットを通じてデータを送信する
				pw.flush();
			}
			catch(Exception e){
				try{
					br.close();
					pw.close();
					sc.close();
					System.out.println("Good Bye !!");
					break;
				}
				catch(Exception ex){
					ex.printStackTrace();
				}

			}
		}
	}
}

class RamdomStrings{
	private final String stringchar = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
	private Random rnd = new Random();
	private StringBuffer sbf = new StringBuffer(15); 

	public String GetRandomString(int cnt){
		for(int i=0; i<cnt; i++){
			int val = rnd.nextInt(stringchar.length());
			sbf.append(stringchar.charAt(val));
		}

		return sbf.toString();
	}
}
```

次回へ続きます．
[Javaを用いたソケット通信　後編](https://qiita.com/akatsubaki/items/ceb935f16c3402d3144d)

# Reference
[高橋麻奈："『やさしいJava』活用編　第5版"](https://www.amazon.co.jp/%E3%82%84%E3%81%95%E3%81%97%E3%81%84Java-%E6%B4%BB%E7%94%A8%E7%B7%A8-%E7%AC%AC5%E7%89%88-%E3%80%8C%E3%82%84%E3%81%95%E3%81%97%E3%81%84%E3%80%8D%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA-%E9%AB%98%E6%A9%8B/dp/4797388277/ref=sr_1_1?s=books&ie=UTF8&qid=1532161063&sr=1-1&keywords=%E3%82%84%E3%81%95%E3%81%97%E3%81%84Java+%E6%B4%BB%E7%94%A8)