2012年11月18日
ネットワーク対戦型ゲームその4-1
すっごく久しぶりに更新です(^-^;)
前回はTCPのサンプルをのせてみたので今回はUDPのサンプルでもw
UDPは以前記述したように
通信速度は速いが信憑性に欠けるものです。
そしてUDPには大きな特徴として
マルチキャストという手法があります。
マルチキャストとは一言でいえば複数の対象に
一度に送信することです。
イメージとしてはメールの一斉送信ですね。
個人的には通信方式について
TCPは電話
UDPはメールのように例えてます。
TCPは通信中常に相手と接続しているので、片方が切断してしまえば
もう片方も切断してしまいます。
すなわち、電話は片方が切ったらお互いに終了しますよね?
また、TCPの接続は1対1で行われます。
それ故に、サーバが複数のクライアントと通信する場合は
マルチスレッドを用いなければなりません。
基本的に電話は1対1です。
もし、自分がA君B君二人と同時に話したければ電話が2台必要です。
これに対してUDPは一方的に送りつけて終わりなので
相手の状態にかかわらず送信はできます。
すなわち、電源が切れてる相手にもメールは送れるのと一緒ですね笑
また、冒頭で述べたようにマルチキャストが使えます。
マルチキャストは一度の送信処理で複数の相手に送ることができる便利な手法です。
メールの一斉送信も一度の送信で済みますよね?
このように、速度や信憑性を考えないで例えてみましたw
雑なプログラムで恐縮ですが前回のようにサンプルを載せてみたいと思います。
動作内容はTCPとUDPの比較がしやすいようにまったく同じにしてあります。
また、図を描くのがめんどいから
プログラムの説明をしやすいようにコメントを異常に書いてみましたww
ソースはサーバとクライアントの通信部分のみ変更しました。
MainFrameとMainPanelは使い回しでお願いします(^-^;)
まずはサーバから
前回はTCPのサンプルをのせてみたので今回はUDPのサンプルでもw
UDPは以前記述したように
通信速度は速いが信憑性に欠けるものです。
そしてUDPには大きな特徴として
マルチキャストという手法があります。
マルチキャストとは一言でいえば複数の対象に
一度に送信することです。
イメージとしてはメールの一斉送信ですね。
個人的には通信方式について
TCPは電話
UDPはメールのように例えてます。
TCPは通信中常に相手と接続しているので、片方が切断してしまえば
もう片方も切断してしまいます。
すなわち、電話は片方が切ったらお互いに終了しますよね?
また、TCPの接続は1対1で行われます。
それ故に、サーバが複数のクライアントと通信する場合は
マルチスレッドを用いなければなりません。
基本的に電話は1対1です。
もし、自分がA君B君二人と同時に話したければ電話が2台必要です。
これに対してUDPは一方的に送りつけて終わりなので
相手の状態にかかわらず送信はできます。
すなわち、電源が切れてる相手にもメールは送れるのと一緒ですね笑
また、冒頭で述べたようにマルチキャストが使えます。
マルチキャストは一度の送信処理で複数の相手に送ることができる便利な手法です。
メールの一斉送信も一度の送信で済みますよね?
このように、速度や信憑性を考えないで例えてみましたw
雑なプログラムで恐縮ですが前回のようにサンプルを載せてみたいと思います。
動作内容はTCPとUDPの比較がしやすいようにまったく同じにしてあります。
また、図を描くのがめんどいから
プログラムの説明をしやすいようにコメントを異常に書いてみましたww
ソースはサーバとクライアントの通信部分のみ変更しました。
MainFrameとMainPanelは使い回しでお願いします(^-^;)
まずはサーバから
import java.io.IOException;
import java.net.*;
import java.util.ArrayList;
import java.util.List;
//UDPサーバのメインクラス
//UDP通信として複数のクライアントへ一度に送信するマルチキャストを実装する
//TCPは複数のクライアントへ送信する場合はクライアント数だけ送信処理を繰り返す必要があった
//だがマルチキャストなら、プログラムの処理は一度のみで
//あとはネットワーク内で勝手にすべてのクライアントへ送ってくれる
//ただしマルチキャストで送信できる相手はマルチキャストアドレスと呼ばれるアドレスに属しているプログラムである
public class MainServer {
//通信待機ポート
//クライアントからの通信を受け付ける
public final static int PORT = 50000;
//リスト
//UDPではTCPのようにソケットでのクライアントの区別が付けられない
//なぜならTCPでは新しいプログラムを立ち上げるたびに、新しいソケットが作られていたが
//UDPでは送信したらそれでおしまいなので、ソケットをリストにしても意味がない
//なので送信元のIPアドレスを格納するようにした
//また同一PCから複数のプログラムを立ち上げても上記の理由ですべて送信元は一緒とみなされてしまう
private static ListIPaddress = new ArrayList ();
//マルチキャスト送信用アドレス
//このアドレスに属しているクライアントへは
//一回でデータを送信することができる
private final static String castIP = "224.1.1.1";
//パケットの寿命 同一LANなら1
//パケットがどこまで届くか、ということらしい
//詳しくはわからないが同一LANで接続するならば1でよいw
private final static int TimeToLive = 1;
//マルチキャストIPとマルチキャストポートをまとめておく
private static InetSocketAddress inetSocketAddress;
//通信待機処理
private void start(){
//受信用バイト配列
byte[] buf = new byte[1024];
try{
//UDPではサーバ、クライアントともにDatagramSocketを使用する
//ここではマルチキャストを利用するのでDatagramSocketのサブクラスであるMulticastSocketを使う
MulticastSocket soc = new MulticastSocket(PORT);
//マルチキャスト用にまとめておく
inetSocketAddress = new InetSocketAddress(castIP, PORT);
//パケット寿命を適応する
soc.setTimeToLive(TimeToLive);
while(true){
try{
//UDPでデータを受け取るにはパケットを受信する
//そのためにDatagramPacketオブジェクトを生成する
DatagramPacket recvPacket = new DatagramPacket(buf, 1024);
//受信待機
//データを受信するまでこの行で停止
//データを受信すればrecvPacketに受け渡される
soc.receive(recvPacket);
//もし、受信したデータの送信元がリストになければ追加しておく
if(IPaddress.indexOf(recvPacket.getAddress()) < 0){
IPaddress.add(recvPacket.getAddress());
}
//受信したデータの送信元が何番目に接続したクライアントか取得する
int number = IPaddress.indexOf(recvPacket.getAddress());
//受信データを文字列化する
//recvPacket.getData()でバイト配列を取得できる
//recvPacket.getLength()で受信データの長さを取得できる
String receiveData = new String(recvPacket.getData(), 0, recvPacket.getLength());
//マルチキャストする文字列を作成する
String sendData = number + ":" + receiveData;
//通信用に文字列をバイトデータ化しておく
byte[] b = sendData.getBytes();
//UDPでは受信も送信もパケットをしようして行う
//なので送信用にパケットを作成する
//引数1にはバイト配列を
//2にはその長さを
//そして3には送信先のIPアドレスとポート番号をまとめたInetSocketAddressオブジェクトを指定する
//この場合ではマルチキャスト用のInetSocketを指定しているが、
//1対1であれば相手のIPとポートを指定してやればよい
DatagramPacket sendPacket= new DatagramPacket(b, b.length, inetSocketAddress);
//そしてソケットのsend()メソッドでパケットを送信する
soc.send(sendPacket);
}catch (SocketException e){
e.printStackTrace();
}catch (IOException e){
e.printStackTrace();
}
}
}catch (IOException e){
e.printStackTrace();
}
}
//メインメソッド
public static void main(String[] args){
MainServer server = new MainServer();
server.start();
}
}
【ゲームプログラミングの最新記事】
投稿者:Sert|00:53|ゲームプログラミング
この記事へのコメント