簡単なソケットプログラミング (Java)
[履歴] [最終更新] (2013/08/14 13:24:38)
最近の投稿
注目の記事

概要

TCP/IP

クラスライブラリjava.net.ServerSocketおよびjava.net.Socketを利用すると、サーバーサイドおよびクライアントサイドのTCP/IP通信が実装できます。一般にTCPは信頼性が高く通信のオーバーヘッドは大きいです。

UDP/IP

クラスライブラリjava.net.DatagramSocketおよびjava.net.DatagramPacketを利用すると、サーバーサイドおよびクライアントサイドのUDP/IP通信が実装できます。一般にUDPは信頼性が低く通信のオーバーヘッドは小さいです。ビデオストリーミングなど、多少のパケットロスが問題にならない通信等で利用されます。

TCP/IP通信

以下のサンプルプログラムでは、クライアントが送信した数値を受信したサーバーは、それを2乗してクライアントに返します。

サーバーサイド

Server.java

import java.net.ServerSocket;
import java.net.Socket;
import java.io.InputStream;
import java.io.DataInputStream;
import java.io.OutputStream;
import java.io.DataOutputStream;

class Server {
    public static void main(String args[]) {
        try {
            int port = Integer.parseInt(args[0]); //サーバ側の待受ポート番号
            ServerSocket ss = new ServerSocket(port);

            while(true) {
                Socket s = ss.accept(); //クライアントからの通信開始要求が来るまで待機

                // 以下、クライアントからの要求発生後
                InputStream is = s.getInputStream(); //クライアントから数値を受信
                DataInputStream dis = new DataInputStream(is);
                int req = dis.readInt();

                OutputStream os = s.getOutputStream(); //二乗した結果を送信
                DataOutputStream dos = new DataOutputStream(os);
                dos.writeInt(req*req);

                // ストリームを閉じる
                dos.close();
                dis.close();
            }
        }
        catch(Exception e) {
            System.out.println("Exception: " + e);
        }
    }
}

クライアントサイド

Client.java

import java.net.Socket;
import java.io.InputStream;
import java.io.DataInputStream;
import java.io.OutputStream;
import java.io.DataOutputStream;

class Client {
    public static void main(String args[]) {
        try {
            String server = args[0];
            int port = Integer.parseInt(args[1]); //サーバー側のポート番号
            Socket s = new Socket(server, port);

            // サーバーに数値を送信
            OutputStream os = s.getOutputStream();
            DataOutputStream dos = new DataOutputStream(os);
            dos.writeInt(Integer.parseInt(args[2]));

            // 演算結果を受信
            InputStream is = s.getInputStream();
            DataInputStream dis = new DataInputStream(is);
            int res = dis.readInt();
            System.out.println(res);

            // ストリームを閉じる
            dis.close();
            dos.close();
        }
        catch (Exception e) {
            System.out.println("Exception: " + e);
        }
    }
}

実行例

サーバーサイド (2乗した結果を返します)

$ javac Server.java && java Server 8888

クライアントサイド

$ javac Client.java && java Client localhost 8888 7
49

UDP/IP通信

クライアントから受信した文字列をサーバー側で表示します。

サーバーサイド

Server.java

import java.net.DatagramSocket;
import java.net.DatagramPacket;

class Server {
    public static void main(String args[]) {
        try {
            int port = Integer.parseInt(args[0]); //サーバー側の待受ポート番号
            DatagramSocket ds = new DatagramSocket(port);

            byte buffer[] = new byte[32]; //受信データを書き込むためのバッファ
            while(true) {
                // 受信したデータは実際にはbufferに格納される
                DatagramPacket dp = new DatagramPacket(buffer, buffer.length);
                ds.receive(dp); //受信するまで待機

                // 以下、受信後
                byte received[] = new byte[dp.getLength()];
                byte tmp[] = dp.getData(); //32バイト (buffer.length)
                for(int i=0; i<dp.getLength(); ++i) received[i]=tmp[i];

                // 文字列化して出力
                String str = new String(received);
                System.out.println(str);
            }
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }
}

クライアントサイド

Client.java

import java.net.DatagramSocket;
import java.net.DatagramPacket;
import java.net.InetAddress;

class Client {
    public static void main(String args[]) {
        try {
            InetAddress addr = InetAddress.getByName(args[0]);
            int port = Integer.parseInt(args[1]); //サーバ側の待受ポート番号

            // 送信するパケットを生成
            byte buffer[] = args[2].getBytes();
            DatagramPacket dp = new DatagramPacket(buffer, buffer.length, addr, port);

            // ソケットを生成してパケットを送信
            DatagramSocket ds = new DatagramSocket();
            ds.send(dp);
            ds.close();
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }
}

実行例

サーバーサイド

$ javac Server.java && java Server 8888
qoosky

クライアントサイド

$ javac Client.java && java Client localhost 8888 qoosky
関連ページ
    概要 TCP/IP ソケットプログラミングについて、C 言語を用いた TCP クライアントの基本的なサンプルコードを記載します。 サンプルコード #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> // ソケット API を利用するため。 #include <unistd.h> //