JAva UDPプロトコルによるサーバクライアント通信

40007 ワード

まず基礎的なことをくどくど言う.
1、2台のコンピュータの間で通信を行うには以下の3つの条件が必要である:IPアドレス、プロトコル、ポート番号
2、IPアドレス、ポートはネットワーク内の異なるコンピュータ間の通信を実現するために、各コンピュータにはIPアドレスという唯一の識別が必要である.一方、1台のホストを区別する複数の異なるアプリケーションは、ポートで識別され、ポート番号の範囲は0-65535であり、0-1023ビットはシステム保持である.IPアドレス+ポート番号がいわゆるSocketを構成しています.
3、Socketソケット:ネットワーク上で唯一識別できるIPアドレスとポートを組み合わせてこそ、唯一識別できる識別子ソケットを構成することができる.Socketの原理メカニズム:通信の両端にSocketがあり、ネットワーク通信は実はSocket間の通信であり、データは2つのSocket間でIOを通じて伝送される.
4、Java中のネットワークサポートはネットワーク通信の異なる階層に対して、Javaは異なるAPIを提供し、その提供するネットワーク機能は4種類ある:InetAddress:ネットワーク上のハードウェア資源を識別するために、主にIPアドレスURL:統一資源ロケータ、URLでネットワーク上のデータを直接読み書きできるSockets:TCPプロトコルを用いて実現されるネットワーク通信Socket関連クラスDatagram:UDPプロトコルを用いてユーザデータ報にデータを保存し、ネットワークを介して通信する.
次のステップで皆さんと共有する私の小さなコードは、demo:socketを利用してクライアントがサーバの現在の時間、日付、指定されたディレクトリの下のファイルリスト(UDP)を取得することを簡単に理解するのに役立ちます.
まず最初の問題は、Javaプログラムでクライアントとサーバを装う方法です.彼らを2つのスレッドに置き去りにして実行することは容易に考えられ、両者が1つの歌と互いに通信しているようだ.多くは言わないで、2つのclassを建てます:clientとserve、Threadクラスを継承して、その構造関数とrun方法を書き換えます.
クライアントヘッダファイル:
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;

serverヘッダファイル:
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;

2つのスレッドのフレームワーク:
public class XXX extends Thread{
    public ClientThread(String threadName){
    super(threadName);
    }
    public void run(){
        balabala
    }
}

もちろん、2つのスレッドを走るものが必要です.そこで、classを新規作成してMultiThreadという名前を取ります.具体的な内容は:
public class TestMultiThread{
    public static void main(String[] args){
    new ServerThread("server").start();
    new Client("client").start();
    }
}

次に,2つのスレッドrunの内容を考えるのも,本論文の核心部分である.最初のステップは、serverから始めなければなりません.まず、ターゲットアクセスがあるサーバがそこに表示されなければなりません.サーバでは、サーバ側のDatagramSocketを作成し、ポートを指定します.
DatagramSocket socket;
socket = new DatagramSocket(8800);

2.クライアントから送信されたデータを受信するデータ・レポートの作成
byte[] data = new byte[1024];//       ,           
DatagramPacket packet = new DatagramPacket(data, data.length);

3.クライアントから送信されたデータを受信する
System.out.println("   :        ,         ");
socket.receive(packet);//                  

ステップ2では、サーバがブロックされています.つまり、クライアントのデータ・レポートが動作するのを待っています.ここでは、クライアントに接続を要求するsocket:Client:1をクライアントに送信するアレイに移行します.サーバのアドレス、ポート番号、データを定義します.
InetAddress address;
address = InetAddress.getByName("localhost");
int port = 8800;
byte[] data = "   :admin;  :123".getBytes();

2.送信されたデータ情報を含むデータ・レポートの作成
DatagramPacket packet = new DatagramPacket(data, data.length, address, port);
3.  DatagramSocket  
DatagramSocket socket = new DatagramSocket();
4.          
socket.send(packet);

第3歩は、サーバ側に戻って、receiveが得たばかりのデータを取得してクライアント情報Serve:1にフィードバックすることです.データを読み出します.
String info = new String(data, 0, packet.getLength());
System.out.println("   :    :" + info);

2.クライアントのアドレス、ポート番号、データの定義
InetAddress address = packet.getAddress();
int port = packet.getPort();
byte[] data2 = "   !".getBytes();
3.     ,         
DatagramPacket packet2 = new DatagramPacket(data2, data2.length, address, port);

4.応答クライアント
socket.send(packet2);

5.クライアントの次の要求を待つ
System.out.println("   :         ");
socket.receive(packet);//                  

第四歩、クライアントは応答した情報を受け取ってから処理し、インタラクションを完了する.
Client:
String reply = new String(data, 0, packet.getLength());
System.out.println("   :    :" + reply);

上記では、UDP転送データレポートがサーバとクライアントでそれぞれどのように操作されているかを試験しましたが、次に、日付時間と指定されたディレクトリのパスの操作を、上記の操作に従って、Clientのrun:
try {
InetAddress address;
address = InetAddress.getByName("localhost");
int port = 8800;
byte[] data = "   :admin;  :123".getBytes();
DatagramPacket packet = new DatagramPacket(data, data.length, address, port);
DatagramSocket socket = new DatagramSocket();
socket.send(packet);


socket.receive(packet);
String reply = new String(data, 0, packet.getLength());
System.out.println("   :    :" + reply);
data = "   :         ".getBytes();
packet = new DatagramPacket(data, data.length, address, port);
socket.send(packet);
socket.receive(packet);
reply = new String(data, 0, packet.getLength());
System.out.println("   :       :" + reply);


data = "   :         ".getBytes();
packet = new DatagramPacket(data, data.length, address, port);
socket.send(packet);
socket.receive(packet);
reply = new String(data, 0, packet.getLength());
System.out.println("   :       :" + reply);



data = "   :            ->C:".getBytes();
packet = new DatagramPacket(data, data.length, address, port);
socket.send(packet);
int count=0;
while(true){
    socket.receive(packet);
    reply = new String(data, 0, packet.getLength());
    if(reply.equals("send all"))break;
    if(count==0)System.out.println("   :   C:       ");
    count++;
    System.out.println(reply);
}
//    
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

Serveのrun:
try {
DatagramSocket socket;
socket = new DatagramSocket(8800);
byte[] data = new byte[1024];//       ,           
DatagramPacket packet = new DatagramPacket(data, data.length);
System.out.println("   :        ,         ");
socket.receive(packet);//                  


String info = new String(data, 0, packet.getLength());
System.out.println("   :    :" + info);
InetAddress address = packet.getAddress();
int port = packet.getPort();
byte[] data2 = "   !".getBytes();
DatagramPacket packet2 = new DatagramPacket(data2, data2.length, address, port);
socket.send(packet2);


System.out.println("   :         ");
socket.receive(packet);//                  


info = new String(data, 0, packet.getLength());
System.out.println("   :    :" + info);
address = packet.getAddress();
port = packet.getPort();
data2 = new GetDate().getDate2().getBytes();
packet2 = new DatagramPacket(data2, data2.length, address, port);
socket.send(packet2);


System.out.println("   :         ");
socket.receive(packet);
info = new String(data, 0, packet.getLength());
System.out.println("   :    :" + info);
address = packet.getAddress();
port = packet.getPort();
data2 = new GetDate().getTime2().getBytes();
packet2 = new DatagramPacket(data2, data2.length, address, port);
socket.send(packet2);


System.out.println("   :         ");
socket.receive(packet);
info = new String(data, 0, packet.getLength());
System.out.println("   :    :" + info);
address = packet.getAddress();
port = packet.getPort();
String[] file=info.split("->");
String [] fileName = new GetFileName().getFileName(file[1]);
for(String name:fileName)
{
data2=name.getBytes();
packet2 = new DatagramPacket(data2, data2.length, address, port);
socket.send(packet2); 
}
data2="send all".getBytes();
packet2 = new DatagramPacket(data2, data2.length, address, port);
socket.send(packet2); 

//     
socket.close();
} catch (IOException e) {
e.printStackTrace();
}

ここでは、指定されたディレクトリのファイルリストを取得する操作に注意して、送信と受信の両方にループ送信受信の方法を使用しています.もちろん、ここでクライアントで使用している「send all」を受信してループを飛び出す方法では、send allのデータレポートを事前に受信して、少ない受信データレポートをスキップすることはありません.さらに注意したいのは、この中で使われている日時パスを得る方法は、対応するclassに書かれた関数を再構築することであり、テーマに関係なく詳しく述べず、最後にファイルのコードを渡すことになります.
上の方は流水帳のようにいくつかの操作を書きましたが、私はカンニングですね.このサーバーはあなたがsend receiveと対応関数を呼び出すには何をすればいいか知っています.現実はどうして可能ですか.そして、お客様にUIインタフェースを提供して、いくつかのボタンを提供しなければなりません.私は何を取得したいですか.あなたのサーバーが私に何を応答するかが真理ですか.だから上の基础の上で、私达のしなければならない操作は:サーバーの端:1つのwhileの循环receiveを使って他の人の送信するデータの报を使って、中のデータの情报によって相応の操作をしてクライアントにフィードバックします:1つの简単なUIのインタフェースを书いて、いくつかのボタンと文本区があって、対応するボタンに対して傍受を行って、あるボタンを押して使用者の望む操作を行って、コードはこうなります
//ServeThread.java
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
public class ServerThread extends Thread{
public ServerThread(String threadName){
super(threadName);
}
public void run(){
//      DatagramSocket,    
try {
DatagramSocket socket;
socket = new DatagramSocket(8800);
//     ,            
byte[] data = new byte[1024];//       ,           
DatagramPacket packet = new DatagramPacket(data, data.length);
//.          
System.out.println("   :        ,         ");
while(true){
socket.receive(packet);//                  
//.    
String info = new String(data, 0, packet.getLength());
System.out.println("   :    :" + info);
if(info.equals("    "))break;
InetAddress address = packet.getAddress();
byte[] data2;
DatagramPacket packet2;
int port = packet.getPort();
if(info.equals("   :         ")){                   
data2 = new GetDate().getDate2().getBytes();
packet2 = new DatagramPacket(data2, data2.length, address, port);
socket.send(packet2);
}
if(info.equals("   :         ")){
data2 = new GetDate().getTime2().getBytes();
packet2 = new DatagramPacket(data2, data2.length, address, port);
socket.send(packet2);
}
if(info.contains("   :            ")){
String[] file=info.split("->");
String [] fileName = new GetFileName().getFileName(file[1]);
for(String name:fileName){
data2=name.getBytes();   
packet2 = new DatagramPacket(data2, data2.length, address, port);
socket.send(packet2); 
}    

data2="send all".getBytes();
packet2 = new DatagramPacket(data2, data2.length, address, port);
socket.send(packet2); 
}
}
socket.close();
System.out.println("        ");
} catch (IOException e) {
e.printStackTrace();
}}}

サーバーのこのコードは何も言うことはありませんが、GetDate.javaとGetFileName.javaの2つのgetDate()とgetFileName()を含むローカル時間日付と指定フォルダのディレクトリを取得するファイルをここに出さなければなりません.
//GetDate.java
import java.util.*;  

public class GetDate {  
    Calendar calendar = null;  

    public GetDate() {  
        calendar = Calendar.getInstance();  
        calendar.setTime(new Date());  
    }  

    public int getYear() {  
        return calendar.get(Calendar.YEAR);  
    }  

    public int getMonth() {  
        return 1 + calendar.get(Calendar.MONTH);  
    }  

    public int getDay() {  
        return calendar.get(Calendar.DAY_OF_MONTH);  
    }  

    public int getHour() {  
        return calendar.get(Calendar.HOUR_OF_DAY);  
    }  

    public int getMinute() {  
        return calendar.get(Calendar.MINUTE);  
    }  

    public int getSecond() {  
        return calendar.get(Calendar.SECOND);  
    }  

    public String getDate() {  
        return getMonth() + "/" + getDay() + "/" + getYear();  
    }  

    public String getTime() {  
        return getHour() + ":" + getMinute() + ":" + getSecond();  
    }  

    public String getDate2() {  
        String yyyy = "0000", mm = "00", dd = "00";  
        yyyy = yyyy + getYear();  
        mm = mm + getMonth();  
        dd = dd + getDay();  
        yyyy = yyyy.substring(yyyy.length() - 4);  
        mm = mm.substring(mm.length() - 2);  
        dd = dd.substring(dd.length() - 2);  
        return yyyy + "/" + mm + "/" + dd;  
    }  

    public String getTime2() {  
        String hh = "00", mm = "00", ss = "00";  
        hh = hh + getHour();  
        mm = mm + getMinute();  
        ss = ss + getSecond();  
        hh = hh.substring(hh.length() - 2, hh.length());  
        mm = mm.substring(mm.length() - 2, mm.length());  
        ss = ss.substring(ss.length() - 2, ss.length());  
        return hh + ":" + mm + ":" + ss;  
    }  
}
//GetFileName.java
import java.io.File;
public class GetFileName
{
    public String [] getFileName(String path)
    {
        File file = new File(path);
        String [] fileName = file.list();
        return fileName;
    }
}

最後に、クライアント・コードが表示されます.4つのボタンが追加されています.「サーバの日付を取得」、「サーバの時間を取得」、「サーバの指定ディレクトリのファイル名を取得」、および指定したディレクトリを入力するためのテキスト・ボックスがあります(英語:および)
//Client.java
import java.awt.Button;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;


import javax.swing.JTextField;


public class Client extends Thread{
    public Client(String threadName){
        super(threadName);
    }
    public void run(){
        String content="";
        //       
        Frame f = new Frame("    ");
        //     
        f.setBounds(400, 200, 400, 300);
        //          
        f.setLayout(new GridLayout(5,1) );

        //       
        Button bu1 = new Button("        ");
        f.add(bu1);
        Button bu2 = new Button("        ");
        f.add(bu2);
        Button bu3 = new Button("           ");
        f.add(bu3);
        JTextField direction;
        direction = new JTextField("      (          ),  “C:”");
        f.add(direction);
        Button bu4 = new Button("  ");
        f.add(bu4);
        //         
        f.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                try {
                    InetAddress address;
                    address = InetAddress.getByName("localhost");
                    int port = 8800; 

                    byte[] data = "    ".getBytes();
                    DatagramPacket packet = new DatagramPacket(data, data.length, address, port);
                    DatagramSocket socket = new DatagramSocket();
                    socket.send(packet);
                    socket.close();
                }catch (IOException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
                System.exit(0);//  JVM
            }
        });
        bu4.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                try {
                    InetAddress address;
                    address = InetAddress.getByName("localhost");
                    int port = 8800; 

                    byte[] data = "    ".getBytes();
                    DatagramPacket packet = new DatagramPacket(data, data.length, address, port);
                    DatagramSocket socket = new DatagramSocket();
                    socket.send(packet);
                    socket.close();
                }catch (IOException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
                System.exit(0);//  JVM
            }});
        bu1.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                try {
                    InetAddress address;
                    address = InetAddress.getByName("localhost");
                    int port = 8800; 

                        byte[] data = "   :         ".getBytes();
                        DatagramPacket packet = new DatagramPacket(data, data.length, address, port);
                        DatagramSocket socket = new DatagramSocket();
                        socket.send(packet);



                        socket.receive(packet);
                        String reply = new String(data, 0, packet.getLength());
                        System.out.println("   :       :" + reply);
                        socket.close();
                }catch (IOException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
            }});

        bu2.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                try {
                    InetAddress address;
                    address = InetAddress.getByName("localhost");
                    int port = 8800; 

                        byte[] data = "   :         ".getBytes();
                        DatagramPacket packet = new DatagramPacket(data, data.length, address, port);
                        DatagramSocket socket = new DatagramSocket();
                        socket.send(packet);



                        socket.receive(packet);
                        String reply = new String(data, 0, packet.getLength());
                        System.out.println("   :       :" + reply);
                        socket.close();
                }catch (IOException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
            }});

        bu3.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                try {
                    InetAddress address;
                    address = InetAddress.getByName("localhost");
                    int port = 8800; 
                    String temp="   :            ->"+direction.getText();
                    System.out.println(temp);
                    byte[] data = temp.getBytes();
                    DatagramPacket packet = new DatagramPacket(data, data.length, address, port);
                    DatagramSocket socket = new DatagramSocket();
                    socket.send(packet);
                    int count=0;
                    while(true){
                        socket.receive(packet);
                        String reply = new String(data, 0, packet.getLength());
                        if(reply.equals("send all"))break;
                        if(count==0)System.out.println("   :           ");
                        count++;
                        System.out.println(reply);
                    }
                    socket.close();
                }catch (IOException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
            }});


        //     
        f.setVisible(true);
    }
}
       TestMultiThread.java
//TestMultiThread.java
public class TestMultiThread{
    public static void main(String[] args){
        new ServerThread("   ").start();
        new Client("client").start();
    }
}

次に、取得時間など、対応する操作によって対応する結果が得られます.
これが今日の分かち合いだ