利用UDP進行java通信

想學習一個類,不如先了解這個類中有什麼方法!

DatagramSocket類 用法詳解:

一:構造方法

    1.DatagramSocket():

  表示創建一個默認的套接字,並綁定到本地地址和一個隨機的端口號

  2.DatagramSocket(int port):

  與上面不同的是,綁定到特定端口號,其它不變

  3.DatagramSocket(int port, InetAddress iad):

  表示創建一個套接字,綁定到特定的端口號及指定地址

  4.DatagramSocket(SocketAddress sad);

  表示創建一個套接字,綁定到特定的套接字地址

 二:基本方法

       1.  close():

  關閉套接字

  2.recevie(DatagramPacket dp):

  接受數據報

  3.send(DatagramPacket dp):

 三:發送數據報:

  DatagramPacket類:

  構造方法:(只列出主要的)

  1.接受類型:

  DatagramPacket(byte[] buf, int length):

  用來接受長度爲length的buf數據(即數據存於字節數組buf中)

  2.發送類型:

  DatagramPacket(byte[] buf, int length, InetAddress address, int port);

  將length長的buf數據發送到指定的地址的端口號處

  DatagramPacket(byte[] buf, int length, SocketAddress address);

     四.讀入數據:

        BufferedReader可以用來讀取文件或者接收來自鍵盤(控制檯)的信息。它比Scanner更加快捷,能夠大幅度縮短程序運行時間。它下面的readline()方法可以一次性讀取一行文字(String),非常方便。需要注意的是,使用BufferedReader對象的readLine()方法必須處理java.io.IOException異常(Exception)。以及,在使用完BufferredReader以後,需要用close()方法關閉流。

         InputStreamReader是字節流通向字符流的橋樑,封裝了InputStream裏面,她以高級的形式一次讀取一個一個字符,以文本格式輸入輸出,可以指定編碼格式;

         每次調用IntputStreamReader中的read()方法都會導致從底層輸入流讀取一個或多個字節。要啓用從字節到字符的有效轉換,可以提前從底層流讀取更多的字節,使其超過滿足當前讀取操作所需的字節

         爲了達到最高效率,可要考慮在 BufferedReader內包裝InputStreamReader:

例如:

        1.接收控制檯信息時:

BufferedReader input = new BufferedReader(new InputStreamReader(System.in));

        2.讀取文件時:

BufferedReader br = New BufferedReader(data);

        3.它的realine()方法:

public static void main(String[] args) throws NumberFormatException, IOException {
        BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
        String s= input.readLine();
        input.read(o);
        }

DatagramPacket表示存放數據的數據報,DatagramSocket表示接受或發送數據報的套接字

三:UDP的簡單應用(簡單通信,可以反覆說話)

代碼實現發送端:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.Scanner;

public class Send {

	public static void main(String[] args) throws Exception {
		//首先建立socket對象
		DatagramSocket dsocket = new DatagramSocket();
		//寫信
		while(true) {//循環說話
			//發送數據
		BufferedReader read = new BufferedReader(new InputStreamReader(System.in));
		String str = read.readLine();
		//發送要通過一個數據包,這個數據包相當有一個信封,信封組成:發送的數據,長度,收件人的地址,收件人的郵編
		DatagramPacket sendpacketage = new DatagramPacket(str.getBytes(),//需要轉換成byte,發送的數據 
				str.length(),//獲取長度
				InetAddress.getByName("127.0.0.1"),//自己的地址,發件人要填自己的地址
				8000); //想象成郵編
		//發送
		dsocket.send(sendpacketage);
		byte []buf = new byte[1024];
		DatagramPacket recivicepacket = new DatagramPacket(buf, buf.length);
		dsocket.receive(recivicepacket);
		System.out.println(new String(buf,0,recivicepacket.getLength()));
	}
	}
}

 

代碼實現接收端:

import java.math.BigInteger;
import java.util.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.Scanner;

public class Recive {

	public static void main(String[] args) throws IOException {
		//需要一個socket
		DatagramSocket dsocket = new DatagramSocket(8000);//相當與對外聲稱自己的郵編,這樣別人可以給做自己寫信
		
		while(true) {
			//接受數據,buffer就是一個接受數據的容器
		byte[] buffer = new byte[1024];
		
		DatagramPacket reservepacket = new DatagramPacket(buffer, buffer.length);
		//真正接受數據,數據已經放入到buffer數組裏面去
		dsocket.receive(reservepacket);
		
		System.out.println(new String(buffer, 0,reservepacket.getLength()));//
		BufferedReader read = new BufferedReader(new InputStreamReader(System.in));
		String str = read.readLine();
		DatagramPacket sendpacket = new DatagramPacket(str.getBytes(),
				str.length(), 
			    reservepacket.getAddress(),//信封上已經有發件人的地址了,應該拿着發件人的地址回信,從信封上找
				reservepacket.getPort());
		dsocket.send(sendpacket);
	}
}
}

1.分析:

將兩者之間的通信可以想象成一個一個寫信的歷程具體在代碼當中!

2.注意:

只能客戶端先發消息給服務端

原因:

如果服務端先發消息,客戶端會接受不到,我認爲原因是在我寫的代碼當中發送時所用到的地址是從接受到的包裹(reservepacket)是取到的,如果沒有先寄過來帶有地址的包裹,就得不到地址,就無法發送消息。

解決方案:

多線程

3.效果圖:

問題:上述代碼只能發送英文但是會發生中文亂碼問題

因爲會以字符數組接受,所以是字符數組的長度而不是字符串數組的長度

改進:send

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.Scanner;

public class send {
	
	public static void main(String[] args) throws Exception {
		
		DatagramSocket sendsocket = new DatagramSocket();
		
		while(true) {
		
			BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
			
			String str = reader.readLine();
			byte[]sendconent = str.getBytes();
			DatagramPacket sendpacket = new DatagramPacket(sendconent,
				sendconent.length,
				InetAddress.getByName("127.0.0.1"),
				8000);
			
			sendsocket.send(sendpacket);
			
			System.out.println("回信啦");
			
			byte[]buffer = new byte[1024];
			
			DatagramPacket recivepacket = new DatagramPacket(buffer, buffer.length);
			
			sendsocket.receive(recivepacket);

			System.out.println(new String(buffer,0,recivepacket.getLength()));
			
		}
		
	}
	
}

recive:

import java.math.BigInteger;
import java.util.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.Scanner;

public class recive {

	public static void main(String[] args) throws IOException {
		DatagramSocket recivesocket = new DatagramSocket(8000);
		while(true) {
		byte[]buffer = new byte[1024];
		
		DatagramPacket recivepacket = new DatagramPacket(buffer, buffer.length);
		
		recivesocket.receive(recivepacket);
		
		System.out.println(new String(buffer,0,recivepacket.getLength()));
		
		BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
		
		String str = reader.readLine();
		
		byte []buf = str.getBytes();
		
		DatagramPacket sendpacket = new DatagramPacket(buf,
				buf.length,
				recivepacket.getAddress(),
				recivepacket.getPort());
		
		recivesocket.send(sendpacket);
	
	}
	
}
}

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章