In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
This article introduces the relevant knowledge of "what is the use of UDP in Java". In the operation of actual cases, many people will encounter such a dilemma, so let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!
The use of UDP in Java
As we all know, most people still use the Java language to develop Android applications. How to use UDP protocol in Java language?
In fact, Socket can be understood as the encapsulation of TCP and UDP protocols at the program usage level, providing some api for programmers to call and develop, which is the most superficial meaning of Socket.
In Java, the classes related to UDP are DatagramSocket, DatagramPacket, and so on, and their use is not emphasized here.
Well, assuming that you have a general understanding of their use, you can officially begin the content of this article.
Initialize a UDPSocket
First create a class called UDPSocket.
Public UDPSocket (Context context) {this.mContext = context; int cpuNumbers = Runtime.getRuntime (). AvailableProcessors (); / / initialize the thread pool mThreadPool = Executors.newFixedThreadPool (cpuNumbers * POOL_SIZE) based on the number of CPU; / / record the time when the object was created lastReceiveTime = System.currentTimeMillis ();}
In the constructor, we do some initialization operations, which is simply to create a thread pool and record the millisecond value of the current time. As for their usefulness, read on:
Public void startUDPSocket () {if (client! = null) return; try {/ / indicates that this Socket listens for data on the set port. Client = new DatagramSocket (CLIENT_PORT); if (receivePacket = = null) {/ / create packet receivePacket = new DatagramPacket (receiveByte, BUFFER_LENGTH);} startSocketThread ();} catch (SocketException e) {e.printStackTrace ();}}
Here we first create a DatagramSocket as a "client". In fact, UDP itself does not have the concept of client and server, only the concept of sender and receiver. Let's treat the sender as a client for the time being.
When you create a DatagramSocket object, you pass in a port number that can be defined within a range, indicating that the DatagramSocket listens for data on this port.
Then a DatagramPacket object is created as the receiving packet for the data.
* call startSocketThread to start the thread that sends and receives data.
/ * start the thread that sends data * / private void startSocketThread () {clientThread = new Thread (new Runnable () {@ Override public void run () {Log.d (TAG, "clientThread is running..."); receiveMessage ();}}); isThreadRunning = true ClientThread.start (); startHeartbeatTimer ();}
First of all, the purpose of the clientThread thread is to call the DatagramSocket receive method, because the receive method is blocked and cannot be placed on the main thread, so a child thread is naturally opened. ReceiveMessage is to deal with the received UDP Datagram. Let's not look at the way to accept the data. After all, no one has sent a message yet, so there will be no collection.
The heartbeat package maintains a "long connection"
Coming to the key points of this article, we all know that UDP itself does not have the concept of connectivity. The scenario of using UDP and TCP on the Android side is a hot spot where one mobile phone connects to another, and both are in the same local area network. When the two do not know the existence of each other, how can they find each other?
Through the heartbeat packet, both parties send a UDP packet at regular intervals. If the other party receives it, it can know the ip of the other party and establish a communication.
Private static final long TIME_OUT = 120 * 1000; private static final long HEARTBEAT_MESSAGE_DURATION = 10 * 1000; / * start heartbeat with timer interval of 10 seconds * / private void startHeartbeatTimer () {timer = new HeartbeatTimer () Timer.setOnScheduleListener (new HeartbeatTimer.OnScheduleListener () {@ Override public void onSchedule () {Log.d (TAG, "timer is onSchedule..."); long duration = System.currentTimeMillis ()-lastReceiveTime; Log.d (TAG, "duration:" + duration) If (duration > TIME_OUT) {/ / if you don't receive my heartbeat for more than two minutes, you don't think the other person is online. Log.d (TAG, "timeout, the other party has been offline"); / / refresh time to re-enter the next heartbeat cycle lastReceiveTime = System.currentTimeMillis ();} else if (duration > HEARTBEAT_MESSAGE_DURATION) {/ / if he does not receive my heartbeat in more than 10 seconds, send another one. String string = "hello,this is a heartbeat message"; sendMessage (string);}); timer.startTimer (0, 1000 * 10);}
The purpose of this heartbeat is to send a message via sendMessage every ten seconds to see if the other person can receive it. If the other party receives the message, refresh the time of the lastReceiveTime.
Here I send a string to the other party every ten seconds.
Private static final String BROADCAST_IP = "192.168.43.255"; / * send heartbeat packet * * @ param message * / public void sendMessage (final String message) {mThreadPool.execute (new Runnable () {@ Override public void run () {try {InetAddress targetAddress = InetAddress.getByName (BROADCAST_IP)) DatagramPacket packet = new DatagramPacket (message.getBytes (), message.length (), targetAddress, CLIENT_PORT); client.send (packet); Log.d (TAG, "data sent successfully");} catch (UnknownHostException e) {e.printStackTrace () } catch (IOException e) {e.printStackTrace ()});}
Here is the code to send a message. When I first filled in the parameters of DatagramPacket, I had a question that that targetAddress was actually my own ip address. The question is, I filled in my own ip address and the port of the other party, how can I find the other party? You may be wondering how the "192.168.43.255" ip address came from and why it is defined this way.
First of all, android phones turn on hotspots, which can be understood as a gateway with a default ip address: "192.168.43.1"
This ip address is not made up by me. This is how it is defined in the Android source code:
WifiStateMachine
Ifcg = mNwService.getInterfaceConfig (intf); if (ifcg! = null) {/ * IP/netmask: 192.168.43.1 IP/netmask 255.255.255.0 * / ifcg.setLinkAddress (NetworkUtils.numericToInetAddress ("192.168.43.1"), 24)) Ifcg.setInterfaceUp (); mNwService.setInterfaceConfig (intf, ifcg);}
So I know the ip address of the so-called hot spot party, and there is another feature when UDP sends messages, that is, the messages sent can be received by devices in the entire gateway, so my own ip address is set as "192.168.43.255", so this ip address and "192.168.43.1" are in the same gateway, and the messages you send can be received.
As for how to determine whether two ip addresses are in the same network segment:
Determine the size of two IP and whether they are in the same network segment
Let's make a phase summary:
First, we create a sender DatagramSocket, start a heartbeat program, and send a heartbeat packet at regular intervals.
Because I know that the ip address of the hotspot is the default "192.168.43.1", and the characteristic of UDP is that the messages sent can be received by devices on the same network segment. So the sender's ip address is "192.168.43.255" on the same network segment as the hotspot.
Events and data
The two modules of event and data are closely related to the business.
First of all, let's talk about the data. You can define the format of the data sent by both parties at will. Of course, I think it is better to define it as the conventional Json format. It can contain some key event fields, such as broadcasting heartbeat packets, answering packets that receive heartbeats to the other party online, timeout offline packets, and various business-related data, and so on.
Of course, when sending data, it is converted to a binary array. There is no problem with sending Chinese characters, pictures, etc., but there may be some details to pay attention to. Just google at any time.
Let's turn to the next incident:
What are the events that have nothing to do with business?
For example:
The DatagramSocket.send method is followed by an event that successfully sends the data.
The DatagramSocket.receive method is followed by an event of successful data reception
When the heartbeat packet is sent for a period of time and no reply is received, it is an event that the connection timed out
Business-related events are related to the data types we mentioned above, device online, heartbeat response, and so on.
How can events be sent and notified to each page? Using Listener or other event bus tripartite libraries is fine, it's up to you to choose.
Processing received messages
/ * process received messages * / private void receiveMessage () {while (isThreadRunning) {try {if (client! = null) {client.receive (receivePacket);} lastReceiveTime = System.currentTimeMillis (); Log.d (TAG, "receive packet success...") } catch (IOException e) {Log.e (TAG, "UDP packet reception failed! Thread stop "); stopUDPSocket (); e.printStackTrace (); return;} if (receivePacket = = null | | receivePacket.getLength () = = 0) {Log.e (TAG," cannot receive UDP data or the received UDP data is empty "); continue } String strReceive = new String (receivePacket.getData (), 0, receivePacket.getLength ()); Log.d (TAG, strReceive + "from" + receivePacket.getAddress (). GetHostAddress () + ":" + receivePacket.getPort ()); / / parse the received json information / / reset the length after each UDP data is received. Otherwise, it may cause the next packet received to be truncated. If (receivePacket! = null) {receivePacket.setLength (BUFFER_LENGTH);}
When processing received messages, there are several points to note:
The receive method is blocked and will always block when the packet is not received, so put it in the child thread.
Call receivePacket.setLength again every time you receive a message
Receive a message to refresh the value of lastReceiveTime and pause the sending of heartbeat packets.
Dealing with the received data in terms of business is the problem of sending data we just talked about, depending on the business.
Concept of "user"
If a mobile phone has turned on a hot spot, if multiple mobile phones are connected to him, it can receive messages sent by multiple mobile phones. If the port of the sender is the same as that of the receiver, you can even receive messages sent by yourself. This is very embarrassing, which means that we should not only delete the messages we send to ourselves, but also distinguish the messages from different mobile phones. At this time, there should be a concept of "users".
The examples of this article are ip, imei, and softversion for creating User objects and which properties can be viewed according to your own business.
/ * create local user information * / private void createUser () {if (localUser = = null) {localUser = new Users ();} if (remoteUser = = null) {remoteUser = new Users ();} localUser.setImei (DeviceUtil.getDeviceId (mContext)); localUser.setSoftVersion (DeviceUtil.getPackageVersionCode (mContext)) If (WifiUtil.getInstance (mContext). IsWifiApEnabled ()) {/ / determine whether the hotspot party localUser.setIp ("192.168.43.1");} else {/ / currently enable the wifi party localUser.setIp (WifiUtil.getInstance (mContext). GetLocalIPAddress ()); remoteUser.setIp (WifiUtil.getInstance (mContext). GetServerIPAddress ()) }} / *
IMEI.
Returns the unique device ID, for example, the IMEI for GSM and the MEID * or ESN for CDMA phones. Return null if device ID is not available. *
* Requires Permission: READ_PHONE_STATE * * @ param context * @ return * / public synchronized static String getDeviceId (Context context) {if (context = = null) {return ";} String imei ="; try {TelephonyManager tm = (TelephonyManager) context.getSystemService (Context.TELEPHONY_SERVICE) If (tm = = null | | TextUtils.isEmpty (tm.getDeviceId () {/ / dual card / dual standby needs to obtain imei through phone1 and phone2. The imei of phone1 is taken by default. Tm = (TelephonyManager) context.getSystemService ("phone1");} if (tm! = null) {imei = tm.getDeviceId ();}} catch (SecurityException e) {e.printStackTrace ();} return imei;}
I won't expand all the code here. If you have the imei number of your phone, it's easy to make an identity distinction. You can either distinguish between different senders or delete the messages you send to yourself. Of course, if you need more information, you can, according to your own business distinction, send this information as a messge sent through Socket.
This is the end of the content of "what is the use of UDP in Java". Thank you for reading. If you want to know more about the industry, you can follow the website, the editor will output more high-quality practical articles for you!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.