ローカルエリアネットワーク内のUDP転送-インスタンスの説明(Java)

10766 ワード

まず、データを受信するために固定されたIPとポートが必要であり、サービス側IPが既知であるサービス側を決定する.
例えば、現在知られているサービス側IPは192.168.137.20、ポート10025である.
サービス側とクライアントは一対多の関係にある
ステップ0
クライアントがサービス側にデータを送信する前に、クライアントから送信されたデータをクライアントに送信し、受信するためのクラスをカプセル化するためのリスナーをサービス側に登録する必要があります.
クライアントにデータを送信するには、まず言わないでください.この时、クライアントのIPアドレスとポート番号を知らないので、まずリスナーを登録するしかありません.クライアントがサービス側にデータを送信し、サービス側が受信すると、サービス側はクライアントのIPアドレスとポート番号を知ることができます.この时、クライアントの送信データに返信することができます.まず、リスナーの登録方法を見てみましょう.
SendToClient

public class SendToClient {

    private DatagramSocket serverSocket = new DatagramSocket(10025);//    socket,    10025(    ),      10025           

    public SendToClient() throws SocketException {

    }

	/*
	*                ,       
	*/
    public void sendDataToClient(StringBuilder str,SocketAddress socketAddress) {
        ......
    }

	/*
	*          
	*/
    public void ReceiveDataFromClient() {
        try {
            while (true) { //       ,               
                byte data[] = new byte[8 * 1024];//                      

				//    packet,      
                DatagramPacket packet = new DatagramPacket(data, data.length);

                serverSocket.receive(packet);//    (          )
				
				/*         String,  split                ,
				       #      ,
				  ,                  ,
				             #90,
				          split("#")            */
                String[] result = new String(packet.getData(), 
                					packet.getOffset(), packet.getLength()).split("#");


				//            
				
                if (!TextUtils.isEmpty(result[0])) {//          
                    //TODO:        
					//  ,   ,               ,          IP      
					//    packet.getSocketAddress()            IP      ,       
                }
            }

        } catch (SocketException e) {
            e.printStackTrace();
            Log.e("######","SocketException"+e);
        } catch (IOException e) {
            e.printStackTrace();
            Log.e("######","IOException"+e);
        }
    }

	//  socket,    
    public void disconnect(){
        serverSocket.close();
        serverSocket.disconnect();
    }

}

使用法
/*
*        
*/
private void registerServerUDP(){
        try {
            sendToClient = new SendToClient();//   SendToClient 
            //Log.e("######ServerService","    ");

        } catch (SocketException e) {
            e.printStackTrace();
            //Log.e("######ServerService","   ip  ");
        }

		//      ,           ,                 
        new Thread(new Runnable() {
            @Override
            public void run() {
           		//  ReceiveDataFromClient()  ,     
                sendToClient.ReceiveDataFromClient();
                //Log.e("######ServerService","         ");
            }
        }).start();
    }

これにより、サービス側のリスナーが構築され、クライアントがサービス側にデータを送信すると、サービス側は受信し、対応する処理を行うことができる.
ステップ1:
次に、クライアントはサービス側にデータを送信できます.
サービス側IPとポートは既知であり、サービス側はすでにリスナーを構築しているため、サービス側にデータを送信することができますが、サービス側はクライアントにデータを送信することができません.私たちは今、クライアントのIPとポート番号を知らないからです.
ステップ:まず、サービス側にデータを送信し、サービス側から送信されたデータを受け入れるためのクラスをカプセル化します.
SendToServer
public class SendToServer {

    private DatagramSocket clientSocket = new DatagramSocket();//    socket          

    public SendToServer() throws SocketException {

    }

/**
*           str:       IP:   IP  
*/
    public void sendDataToServer(StringBuilder str,String IP) {

        try {
            InetAddress serverAddress = InetAddress.getByName(IP);//  IP    ,    IP,192.168.137.20(    )
            byte data[] = str.toString().getBytes();//           
            DatagramPacket packetToServer = new DatagramPacket(data, data.length ,serverAddress,10025);//          packet ,      socket    
            clientSocket.send(packetToServer);//     10025(    )    
        } catch (SocketException e) {
            e.printStackTrace();
            Log.e("######SendToServer","SocketException"+e);
        } catch (UnknownHostException e) {
            e.printStackTrace();
            Log.e("######SendToServer","UnknownHostException"+e);
        } catch (IOException e) {
            e.printStackTrace();
            Log.e("######SendToServer","IOException"+e);
        }
    }

	/*
	*           ,        ,               
	*/
   public void ReceiveDataFromServer() {

        try {
            while(true) {//       ,               
                byte fromServer[] = new byte[4 * 1024];//                      
                //    packet,      
                DatagramPacket packet = new DatagramPacket(fromServer, fromServer.length);
                clientSocket.receive(packet);//    (          )

				//         String
                String result = new String(packet.getData(), packet.getOffset(), packet.getLength());

				//            
                if (!TextUtils.isEmpty(result)) {//          
                    //TODO:        
                    //   ,                ,           IP      
                    //    192.168.137.20(    ) 10025(    )
                    //     packet.getSocketAddress()   
                }
                //Log.e("######SendToServer", "           :" + result);
            }

        } catch (SocketException e) {
            e.printStackTrace();
            Log.e("######SendToServer","SocketException"+e);
        } catch (IOException e) {
            e.printStackTrace();
            Log.e("######SendToServer","IOException"+e);
        }
    }

	//  socket,    
    public void disconnect(){
        clientSocket.close();
        clientSocket.disconnect();
    }

}

使用方法:
/*
*             
*/
private void registerClientUDP(){
        try {
            sendToServer = new SendToServer();//   SendToServer 
            Log.e("######GameActivity","    ");
        } catch (SocketException e) {
            e.printStackTrace();
            //Log.e("######GameActivity","   ip  ");
        }
		//           ,             
		//      ,           ,                 
        new Thread(new Runnable() {
            @Override
            public void run() {
           		//  ReceiveDataFromClient()  ,     
                sendToServer.ReceiveDataFromServer();
                Log.e("######GameActivity","         ");
            }
        }).start();
    } 
    
	private void sendMessageToServer(final StringBuilder s){//       
        new Thread(new Runnable() {//           (                )
            @Override
            public void run() {
                sendToServer.sendDataToServer(s,serverIP);//             ,      ,s:      ,serverIP:   IP
            }
        }).start();
    }

変数sタイプはStringBuilderに設定しましたが、使用中はStringに完全に設定できます.
これにより、サービス側にデータを送信しました.
ステップ2
サービス側はクライアントからのデータを受け取り、同時にクライアントに返信する
SendToClientクラスでは、前述のクラスのコードが貼られていません.コードは次のとおりです.SendToClientのsendDataToClient()関数
/*
*                   ,
*                          
*      String IP   SocketAddress socketAddress
*                   ,  packet.getSocketAddress()        SocketAddress  
*           IP      , SendToServer  sendDataToServer   
*     DatagramPacket packetToServer = new DatagramPacket(data, data.length ,serverAddress,10025);
*             packet  ,  socket(    ) packet(     )       
*         ,        packet.getSocketAddress()       packet(     )
*   socket(   ) packet(     )          
*/
public void sendDataToClient(StringBuilder str,SocketAddress socketAddress) {
        try {
            byte data[] = str.toString().getBytes();//            
            //              packet
            DatagramPacket packetToClient = new DatagramPacket(data, data.length ,socketAddress);
            //  socket        
            serverSocket.send(packetToClient);
        } catch (SocketException e) {
            e.printStackTrace();
            Log.e("######","SocketException"+e);
        } catch (UnknownHostException e) {
            e.printStackTrace();
            Log.e("######","UnknownHostException"+e);
        } catch (IOException e) {
            e.printStackTrace();
            Log.e("######","IOException"+e);
        }
    }

使用法

	private void sendMessageToServer(final StringBuilder s,SocketAddress socketAddress){//       
        new Thread(new Runnable() {//           (                )
            @Override
            public void run() {
            	sendToClient.sendDataToClient(s,socketAddress);//             ,      ,s:      ,SocketAddress :          
            }
        }).start();
    }

これにより、サービス側はクライアントへの返信に成功しました.
ステップ3
クライアントはサービス側からのデータを受信する
最初のステップでは、クライアントのリスナーも作成しました.データを受信すると、リスナーが傍受し、受信したデータを処理できます.
SendToServerのReceiveDataFromServer()関数
/*
	*           ,        ,               
	*/
   public void ReceiveDataFromServer() {

        try {
            while(true) {//       ,               
                byte fromServer[] = new byte[4 * 1024];//                      
                //    packet,      
                DatagramPacket packet = new DatagramPacket(fromServer, fromServer.length);
                clientSocket.receive(packet);//    (          )

				//         String
                String result = new String(packet.getData(), packet.getOffset(), packet.getLength());

				//            
                if (!TextUtils.isEmpty(result)) {//          
                    //TODO:        
                    //   ,                ,           IP      
                    //    192.168.137.20(    ) 10025(    )
                    //     packet.getSocketAddress()   
                }
                //Log.e("######SendToServer", "           :" + result);
            }

        } catch (SocketException e) {
            e.printStackTrace();
            Log.e("######SendToServer","SocketException"+e);
        } catch (IOException e) {
            e.printStackTrace();
            Log.e("######SendToServer","IOException"+e);
        }
    }

最後に
1、クライアントがサービス側にデータを送信する2、サービス側受信データ3、サービス側返信クライアント4、クライアント受信データ
また、UDPの特徴1、TCPに比べて、伝送前に接続を確立する必要はなく、IPが直接データを送信することができることを知っている2、伝送データが速く、メモリが小さい3、最大速度でデータを伝送することができますが、データの正確性を保証することはできません
そして、サービス側とクライアントは同じローカルエリアネットワークの下でなければなりませんよ.
                                                                                                                    to my dear   .