UDP協(xié)議(用戶數(shù)據(jù)報(bào)協(xié)議)是一種不可靠的網(wǎng)絡(luò)協(xié)議,它在通信實(shí)例的兩端各建立一個(gè)Socket,但是這兩個(gè)Socket之間并沒有虛擬鏈路,這兩個(gè)Socket只是發(fā)送,接收數(shù)據(jù)報(bào)的對(duì)象。
成都創(chuàng)新互聯(lián)公司是一家集網(wǎng)站建設(shè),平川企業(yè)網(wǎng)站建設(shè),平川品牌網(wǎng)站建設(shè),網(wǎng)站定制,平川網(wǎng)站建設(shè)報(bào)價(jià),網(wǎng)絡(luò)營(yíng)銷,網(wǎng)絡(luò)優(yōu)化,平川網(wǎng)站推廣為一體的創(chuàng)新建站企業(yè),幫助傳統(tǒng)企業(yè)提升企業(yè)形象加強(qiáng)企業(yè)競(jìng)爭(zhēng)力。可充分滿足這一群體相比中小企業(yè)更為豐富、高端、多元的互聯(lián)網(wǎng)需求。同時(shí)我們時(shí)刻保持專業(yè)、時(shí)尚、前沿,時(shí)刻以成就客戶成長(zhǎng)自我,堅(jiān)持不斷學(xué)習(xí)、思考、沉淀、凈化自己,讓我們?yōu)楦嗟钠髽I(yè)打造出實(shí)用型網(wǎng)站。
UDP的優(yōu)缺點(diǎn):
1. 因?yàn)閁DP協(xié)議是面向非連接的協(xié)議,沒有建立連接的過程,因此它的通信效率很高。很適合一些即時(shí)性很強(qiáng)的應(yīng)用場(chǎng)景。
2.因?yàn)樵谡酵ㄐ徘安槐嘏c對(duì)方先連接,不管對(duì)方狀態(tài)就直接發(fā)送,至于對(duì)方是否可以收到這些數(shù)據(jù)內(nèi)容,UDP無法控制,所以說UDP是一種不可靠的協(xié)議。
3.傳輸大小限制在64KB以下,這個(gè)尤其要注意,在做這個(gè)實(shí)例的時(shí)候,因?yàn)闆]有考慮到這個(gè),直接傳了一張大圖,結(jié)果找了半天的原因。
Java使用DatagramSocket代表UDP協(xié)議的Socket,它唯一的作用是接收和發(fā)送數(shù)據(jù)報(bào),至于數(shù)據(jù)究竟發(fā)給誰(shuí),DatagramSocket并不清楚;具體發(fā)送的目的地是由DatagramPacket自身決定。當(dāng)Client/Server程序使用UDP協(xié)議時(shí),實(shí)際上并沒有嚴(yán)格的服務(wù)器和客戶端的區(qū)分。通常固定IP地址,固定端口的DatagramSocket對(duì)象所在程序被稱為服務(wù)器,因?yàn)橛泄潭ǖ腎P,端口地址,其他客戶端的數(shù)據(jù)報(bào)可以直接發(fā)送到服務(wù)器上。
接收數(shù)據(jù)的DatagramPacket在實(shí)例化時(shí)無需指定端口和IP地址,給出數(shù)據(jù)數(shù)據(jù)的字節(jié)數(shù)組以及長(zhǎng)度即可。然后調(diào)用DatagramSocket的receive()方法等待數(shù)據(jù)報(bào)的到來,該方法阻塞線程直到受到一個(gè)數(shù)據(jù)報(bào)為止。
發(fā)送數(shù)據(jù)的DatagramPacket不同的是,需要給出完整的目的地,包括IP地址和端口,這樣數(shù)據(jù)報(bào)才能知道將數(shù)據(jù)發(fā)給誰(shuí)。當(dāng)服務(wù)器接收到一個(gè)DatagramPacket對(duì)象后,如果想向該數(shù)據(jù)報(bào)的發(fā)送者反饋一些消息,但由于UDP協(xié)議是面向非連接的,所以不知道數(shù)據(jù)報(bào)是誰(shuí)發(fā)送過來的,但程序可以調(diào)用DatagramPacket的getAddress()(返回一個(gè)InetAddress對(duì)象,發(fā)報(bào)的IP地址),getPort()(返回發(fā)報(bào)的端口)和getSocketAddress()(返回一個(gè)SocketAddress對(duì)象,該對(duì)象可以同時(shí)代表IP地址和端口)。
實(shí)現(xiàn)思路:每個(gè)客戶端啟動(dòng)時(shí)都會(huì)向服務(wù)端發(fā)送一個(gè)字符串,該字符串代表該客戶端已經(jīng)上線,并在服務(wù)端將每個(gè)客戶端的發(fā)報(bào)地址(即SocketAddress對(duì)象)保存在一個(gè)Set集合中。當(dāng)點(diǎn)擊任意一個(gè)上線的客戶端的發(fā)送圖片按鈕,該圖片數(shù)據(jù)就會(huì)被發(fā)送到服務(wù)端上,服務(wù)端遍歷SocketAddress集合,并將圖片數(shù)據(jù)轉(zhuǎn)發(fā)到每個(gè)SocketAddress對(duì)應(yīng)的客戶端上,就實(shí)現(xiàn)了簡(jiǎn)單的圖片群發(fā)。具體代碼如下:
客戶端發(fā)送數(shù)據(jù)報(bào)的工具類:
public class DatagramUtil
{
public static final int BOADCAST_PORT = 8888;
public static final String DEST_IP = "192.168.1.101";
private static final int DATA_LEN = 50000;
//定義本程序私聊的Socket實(shí)例
private DatagramSocket singleSocket = null;
//定義接收網(wǎng)絡(luò)數(shù)據(jù)的字符數(shù)組
byte[] inBuff = new byte[DATA_LEN];
private Handler handler;
//構(gòu)造器,初始化資源
public DatagramUtil(Handler handler) throws Exception
{
this.handler = handler;
//創(chuàng)建用于私聊的DatagramSocket對(duì)象
singleSocket = new DatagramSocket();
new ReadSingle().start();
}
//定義單獨(dú)用戶發(fā)送消息的方法
public void sendSingle(byte[] msg)
{
try
{
DatagramPacket packet = new DatagramPacket(new byte[0] , 0 , InetAddress.getByName(DEST_IP) , BOADCAST_PORT);
packet.setData(msg);
singleSocket.send(packet);
}
catch (IOException e)
{
e.printStackTrace();
}
}
//不斷地從DatagramSocket中讀取數(shù)據(jù)的線程
class ReadSingle extends Thread
{
byte[] singleBuff = new byte[DATA_LEN];
private DatagramPacket singlePacket = new DatagramPacket(singleBuff , singleBuff.length);
@Override
public void run()
{
while (true)
{
// 讀取Socket中的數(shù)據(jù)
try
{
//讀取Socket中的數(shù)據(jù)
singleSocket.receive(singlePacket);
//處理得到的消息
Message msg = new Message();
msg.what = 0x123;
msg.obj = singleBuff;
handler.sendMessage(msg);
}
catch (IOException e)
{
e.printStackTrace();
if (singleSocket != null)
{
//關(guān)閉該Socket對(duì)象
singleSocket.close();
}
}
}
}
}
}收到服務(wù)端發(fā)來的圖片數(shù)據(jù)時(shí),使用Handler更新UI。
public class MainActivity extends Activity
{
private Button button;
private ImageView img;
private DatagramUtil datagramUtil;
Handler handler = new Handler()
{
@Override
public void handleMessage(Message msg)
{
if (msg.what == 0x123)
{
byte[] result = (byte[]) msg.obj;
img.setImageBitmap(BitmapFactory.decodeByteArray(result , 0 , result.length));
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
button = (Button) findViewById(R.id.send_img_all);
img = (ImageView) findViewById(R.id.receiver_img);
try
{
datagramUtil = new DatagramUtil(handler);
sendData(stringYoByte());
}
catch (Exception e)
{
e.printStackTrace();
}
button.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View view)
{
sendData(bitMapToByte());
}
});
}
private void sendData(final byte[] msg)
{
new Thread()
{
@Override
public void run()
{
datagramUtil.sendSingle(msg);
}
}.start();
}
public byte[] bitMapToByte()
{
Bitmap bitmap = BitmapFactory.decodeResource(getResources() , R.drawable.wenqing);
ByteArrayOutputStream byteArray = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG , 100 , byteArray);
bitmap.recycle();
return byteArray.toByteArray();
}
public byte[] stringYoByte()
{
String loginStr = "hello";
return loginStr.getBytes();
}
}服務(wù)端代碼(運(yùn)行該Java程序即可):
public class UDPServer
{
public static final int PORT = 8888;
private static final int DATA_LEN = 50000;
byte[] inBuff = new byte[DATA_LEN];
private DatagramPacket inPacket = new DatagramPacket(inBuff , inBuff.length);
private DatagramPacket outPacket;
private DatagramSocket serverSocket;
private Set<SocketAddress> socketAddressList = Collections.synchronizedSet(new HashSet<SocketAddress>());
public void init() throws IOException
{
serverSocket = new DatagramSocket(PORT);
while (true)
{
serverSocket.receive(inPacket);
String result = new String(inBuff , 0 , inBuff.length);
if (result.trim().equals("hello"))
{
socketAddressList.add(inPacket.getSocketAddress());
}
else
{
for (Iterator<SocketAddress> iterator = socketAddressList.iterator(); iterator.hasNext() ; )
{
SocketAddress socketAddress = iterator.next();
outPacket = new DatagramPacket(inBuff , inBuff.length , socketAddress);
serverSocket.send(outPacket);
}
}
}
}
public static void main(String[] args) throws IOException
{
new UDPServer().init();
}
}這樣實(shí)現(xiàn)了簡(jiǎn)單的圖片群發(fā)的效果。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持創(chuàng)新互聯(lián)。
文章題目:java基于UDP實(shí)現(xiàn)圖片群發(fā)功能
當(dāng)前URL:http://chinadenli.net/article2/geeooc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)頁(yè)設(shè)計(jì)公司、自適應(yīng)網(wǎng)站、ChatGPT、網(wǎng)站設(shè)計(jì)、網(wǎng)站建設(shè)、App設(shè)計(jì)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)