Java UDP Socket programming and javaudpsocket Programming
UDP protocol
The services provided by UDP protocol are different from the end-to-end services provided by TCP protocol. It is non-connection oriented and is an unreliable protocol. UDP sockets do not need to be connected before use. In fact, UDP implements two functions:
1) added Ports Based on the IP protocol;
2) The system detects possible data errors during transmission and discards damaged data.
Java support for UDP
Java uses UDP sockets through the DatagramPacket and DatagramSocket classes. Both the client and server send and receive data through the send () and receive () Methods of the DatagramSocket, use mongorampacket to package the data to be sent or received. When sending information, Java creates a mongorampacket instance that contains the information to be sent, and passes it as a parameter to the send () method of the mongoramsocket instance. When receiving information, java programs first create a mongorampacket instance, which allocates some space in advance and stores the received information in the space, then, the instance is passed as a parameter to the receive () method of the DatagramSocket instance. When creating a mongorampacket instance, note that if the instance is used to wrap the data to be received, the remote host and port of the data source are not specified, you only need to specify a byte array of cached data (after the receive () method is called to receive data, the source address, port, and other information will be automatically included in the DatagramPacket instance ), if the instance is used to wrap the data to be sent, specify the target host and port to be sent.
Steps for establishing UDP Communication
The UDP client first sends a data packet to the server that is passively waiting for the contact. A typical UDP client must go through the following three steps:
1. Create an initramsocket instance. You can selectively set the local address and port number. If the port number is set, the client listens to the data sent from the server on the port number;
2. Use the send () and receive () Methods of the initramsocket instance to send and receive the initrampacket instance for communication;
3. After the communication is complete, call the close () method of the DatagramSocket instance to close the socket.
Because UDP is not connected, the UDP server does not need to wait for client requests to establish a connection. In addition, the UDP server uses the same socket for all communications, which is different from the TCP server. The TCP server creates a new socket for each successful returned accept () method. A typical UDP server must go through the following three steps:
1. Create an initramsocket instance, specify the local port number, and select a local address. At this time, the server is ready to receive data packets from any client;
2. Use the receive () method of the initramsocket instance to receive an initrampacket instance. When the receive () method returns, the data packet contains the client address, in this way, you will know where the reply information should be sent;
3. Use the send () method of the mongoramsocket instance to return the mongorampacket instance to the server.
The UDP program blocks the receive () method until it receives a data packet or waits for timeout. Because UDP is an unreliable protocol, if you do not receive the DatagramPacket, the program will be blocked in the receive () method, so that the client will never receive the data sent back from the server, but there are no prompts. To avoid this problem, we use the setSoTimeout () method of the DatagramSocket class on the client to set the maximum blocking time of the receive () method, and specify the number of re-sent data packets. If each blocking times out, if the number of resends reaches the upper limit, the client is closed.
The following is a Demo of UDP Communication on the client server (with no multithreading). The client listens to received data on the local port 2222 and sends the string "Hello UDPserver" to the local port 3222, the server monitors the received data on the local port 3222. If the data is received, the string "Hello UDPclient" is returned to port 2222 of the client. On the client side, because the program may always block the receive () method, we use the setSoTimeout () method of the DatagramSocket instance to specify the maximum blocking time timeout of the receive () on the client side, and set the number of data resends MAXNUM. If the data is still not received from the server, we will close the client.
1 import java. io. IOException; 2 import java. io. interruptedIOException; 3 import java.net. datagramPacket; 4 import java.net. datagramSocket; 5 import java.net. inetAddress; 6 7 public class UdpClient {8 private static final int MAXNUM = 5; // you can specify the maximum number of times for resending data. 9 private static final int TIMEOUT = 5000; // set the timeout value for receiving data 10 private static final int CLIENT_PORT = 2222; 11 private static final int SERVER_PORT = 322 2; 12 private static final int REV_SIZE = 1024; // size of the storage space for receiving data 13 14 public static void main (String [] args) throws IOException {15 String str_send = "Hello UDPserver"; // the String to be sent 16 byte [] buf_rev = new byte [REV_SIZE]; // The bucket to be received 17 18/* The first step is to instantiate DatagramSocket */19 DatagramSocket mSoc = new DatagramSocket (CLIENT_PORT); 20 mSoc. setSoTimeout (TIMEOUT); // sets the maximum blocking time for receiving data 21 22/* The second step instantiates the mongorampacket used for sending and the D used for receiving AtagramPacket */23 InetAddress inetAddress = InetAddress. getLocalHost (); 24 hour rampacket data_send = new hour rampacket (hour (), 25 str_send.length (), inetAddress, SERVER_PORT); 26 27 hour rampacket data_rev = new hour rampacket (buf_rev, REV_SIZE ); 28 29 30/* Step 3: send rampacket send data, and receive receives data */31 int send_count = 0; // The number of data resends 32 boolean revResponse = false; // whether the flag of the received data is 33 while (! RevResponse & send_count <MAXNUM) {34 try {35 mSoc. send (data_send); // send data 36 mSoc. receive (data_rev); // receive data 37 if (! Data_rev.getAddress (). getHostAddress () 38. equals (InetAddress. getLocalHost (). getHostAddress () {39 throw new IOException (40 "Received packet from an umknown source"); 41} 42 revResponse = true; 43} catch (InterruptedIOException e) {44 // If blocking times out when receiving data, resend and reduce the number of resends at a time 45 send_count + = 1; 46 System. out. println ("Time out," + (MAXNUM-send_count) 47 + "more tries... "); 48} 49} 50 if (revResponse) {51 // print 52 System if the data is received. out. println ("client received ed data from server:"); 53 String str_receive = new String (data_rev.getData (), data_rev.getLength () 55 + "from" 56 + data_rev.getAddress (). getHostAddress () 57 + ":" 58 + data_rev.getPort (); 59 System. out. println (str_receive); 60 // Since dp_receive receives data, its internal message length value will change to the actual number of received messages in bytes, 61 // so here we need to reset the internal message length of dp_receive to 102462 data_rev.setLength (REV_SIZE); 63} else {64 // If MAXNUM data is resold, if the data sent from the server is still not obtained, the following information is printed: 65 System. out. println ("No response -- give up. "); 66} 67 68/* Step 4 disable mongorampacket */69 mSoc. close (); 70} 71 72}UdpClient 1 import java. io. IOException; 2 import java.net. datagramPacket; 3 import java.net. datagramSocket; 4 import java.net. inetAddress; 5 6 public class UdpServer {7 8 private static final int SERVER_PORT = 3222; 9 private static final int REV_SIZE = 1024; // size of the storage space for receiving data 10 11 public static void main (String [] args) throws IOException {12 byte [] buf_rev = new byte [REV_SIZE]; 13 String str_send = "Hello UDPclient"; 14/* instantiate initramsocket */15 initramsocket mSoc = new initramsocket (SERVER_PORT ); 16 17/* Step 2 instantiate the mongorampacket used to receive and receive data from mongoramsocket */18 mongorampacket data_rev = new mongorampacket (buf_rev, REV_SIZE); 19 boolean f = true; 20 while (f) {21 mSoc. receive (data_rev); 22 InetAddress inetAddress = data_rev.getAddress (); 23 int port = data_rev.getPort (); 24 System. out. println ("server received data from client:"); 25 String str_rev = new String (data_rev.getData (), data_rev.getLength () 27 + "from" + inetAddress. getHostAddress () + ":" + port; 28 System. out. println (str_rev); 29 30/* The initrampacket used for sending is instantiated in step 3, and sent out from the initramsocket */31 initrampacket data_send = new initrampacket (str_send.getBytes (), 32 str_send.length (), inetAddress, port); 33 mSoc. send (data_send); 34 35/* 36 * Since dp_receive receives data, its internal message length value will change to the actual number of received messages in bytes, 37 * Here we need to reset the internal message length of dp_receive to 102438 */39 data_rev.setLength (REV_SIZE); 40} 41 mSoc. close (); 42 43} 44}UdpServer
If the server is not running, receive () Fails. The running result is as follows:
2. UDP data packets can load the most data, and the maximum data transmitted at a time is 65507 bytes.
When a message arrives from the network, the data contained in the message is returned by the TCP read () method or the UDP receive () method, data is stored in a first-in-first-out receiving data queue. For TCP sockets that have established connections, all accepted but not transmitted bytes are considered as a continuous byte sequence. However, for UDP sockets, the received data may come from different senders. The data received by a UDP socket is stored in a message queue, and each message is associated with its source address, only one message is returned for each receive () call. If the receive () method is called in an initrampacket instance whose cache size is n and the length of the first message in the receiving team is greater than n, then receive () the method returns only the first n Bytes of the message. The excess part is automatically discarded and no message loss notification is sent to the recipient!
For this reason, the receiver should provide a mongorampacket instance with sufficient cache space to fully store the maximum length of messages allowed by the application protocol when the receive () method is called. The maximum data size allowed to be transmitted in a mongorampacket instance is 65507 bytes, that is, the maximum data that UDP data packets can load. Therefore, a cache array of about 65600 bytes can be used to accept data.
3. The internal message length value of mongorampacket changes after the received data to the actual length value of the received data.
Each mongorampacket instance contains an internal message length value. Its initial value is the length value of the byte cache array. Once the instance receives the message, the length value is changed to the actual length value of the received message, which can be tested using the getLength () method of the DatagramPacket class. If an application uses the same DatagramPacket instance to call the receive () method multiple times, the length of the internal message must be explicitly reset to the actual length of the cache before each call, to avoid data loss.
4. The getData () method of mongorampacket always returns the original size of the buffer, ignoring the internal offset and length of the actual data.
Because the getData () method of mongorampacket always returns the original size of the buffer array, that is, the size specified when the buffer array is created at the beginning. In the above program, the length is 1024, therefore, if we want to obtain the received data, we must intercept the array returned by the getData () method that contains only the part of the received data.
We can use the Arrays. copyOfRange () method to implement the above functions in one step:
Byte [] destbuf = Arrays. copyOfRange (data_rev.getData (), data_rev.getOffset (),
Data_rev.getOffset () + data_rev.getLength ());
Of course, if you want to convert the received byte array to a String, you can also use the method of directly adding a String object in this program:
New String (data_rev.getData (), data_rev.getOffset (),
Data_rev.getOffset () + data_rev.getLength ());
References:
[Java TCP/IP Socket] UDP Socket (including code) http://blog.csdn.net/ns_code/article/details/14128987
Java TCP/IP Socket programming