The 17th Chapter Network programming
17.4 Network programming based on UDP protocol
UDP protocol is an unreliable network protocol, it establishes a socket on both ends of the communication instance, but there is no virtual link between the two sockets, these two sockets are just the objects that send and receive datagrams. Java provides the Datagramsocket object as a UDP-based socket, using Datagrampacket to represent Datagramsocket sent and received datagrams.
17.4.1 UDP Protocol Basics
The UDP protocol is the abbreviation for the English User Datagram protocol, which is the client datagram protocol, which is primarily used to support network connections that require data to be transferred between computers. UDP protocol has been used for many years since its inception, although the UDP protocol is not as widely used as TCP protocol, but the UDP protocol is still a very practical and feasible network Transport layer protocol. Especially in some real-time application scenarios, such as online games, video conferencing and so on, the UDP protocol has a very fast and unique charm.
UDP protocol is a non-connection-oriented protocol, non-connectivity refers to the formal communication before the need to establish a connection with the other party, regardless of the status of the other party directly sent. As to whether the other party can receive the data content, the UDP protocol cannot control, so the UDP protocol is an unreliable protocol. The UDP protocol is suitable for applications where only a small amount of data is transmitted at a time and the reliability requirements are low.
Like the TCP protocol described earlier, the UDP protocol is directly above the IP protocol. In fact, the IP protocol belongs to the network layer protocol of the OSI Reference Model, while the UDP protocol and TCP protocol are all transport layer protocols.
Because the UDP protocol is for a non-connected protocol, there is no process to establish a connection, so it is highly efficient in communication, but because of this, it is less reliable than the TCP protocol.
The main function of the UDP protocol is to complete the transformation between the network data stream and the datagram--at the transmitting end of the information, the UDP protocol encapsulates the network data stream into the datagram, then sends the datagram, and at the receiving end of the information, the UDP protocol transforms the datagram into the actual data content.
It can be considered that the UDP socket is similar to the terminal, the datagram is similar to the container, and the function of the terminal is to send and receive the container, while the Datagramsocket function is to send and receive the datagram. Therefore, for the UDP-based communication between the two sides, there is no so-called client and server-side concept.
The UDP protocol and TCP protocol are simple comparisons.
TCP protocol: Reliable, unlimited transmission size, but need to connect the settling time, error control overhead.
UDP protocol: Unreliable, error control overhead is small, transmission size is limited to less than 64KB, there is no need to establish a connection.
17.4.2 sending and receiving data using Datagramsocket (1)
Java uses datagramsocket on behalf of the UDP protocol Socket,datagramsocket itself is just a pier, not maintaining state, can not generate IO stream, its only role is to receive and send datagrams, Java uses Datagrampacket to represent datagrams, and the data that Datagramsocket receives and sends is done through Datagrampacket objects.
First look at the Datagramsocket constructor.
Datagramsocket (): Creates an Datagramsocket instance and binds the object to a native default IP address, a randomly selected port in all available ports in this computer.
Datagramsocket (int prot): Creates an Datagramsocket instance and binds the object to the native default IP address, specifying the port.
Datagramsocket (int port, inetaddress laddr): Creates a Datagramsocket instance and binds the object to the specified IP address, specifying the port.
A Datagramsocket instance can be created from any of the three constructors above, typically creating a Datagramsocket instance of the specified port when the server is created-so that other clients can send data to that server. Once the Datagramsocket instance has been obtained, it is possible to receive and send the data in the following two ways.
Receive (Datagrampacket P): Receives datagrams from this datagramsocket.
Send (Datagrampacket p): Sends the datagram outward with the Datagramsocket object.
As can be seen from the above two methods, using Datagramsocket to send the datagram, Datagramsocket does not know where to send the datagram, but is determined by the datagrampacket itself to determine the destination of the datagram. Just as the pier does not know the destination of each container, the terminal simply sends the containers out, and the container itself contains the container's destination.
Here's a look at the Datagrampacket constructor.
Datagrampacket (byte[] buf,int length): Creates a Datagrampacket object with an empty array, which is the object of receiving data from Datagramsocket.
Datagrampacket (byte[] buf, int length, inetaddress addr, int port): Creates a Datagrampacket object in an array containing data. The IP address and port are also specified when the Datagrampacket object is created-this determines the destination of the datagram.
Datagrampacket (byte[] buf, int offset, int length): Creates a Datagrampacket object with an empty array and specifies that the received data is placed in the BUF array, starting with offset, Put up to a maximum of length bytes.
Datagrampacket (byte[] buf, int offset, int length, inetaddress address, int port): Creates a Datagrampacket object for sending, Specifies that the send BUF array begins with offset, with a total length of bytes.
When the Client/server program uses the UDP protocol, there is actually no obvious server side and client, because both parties need to first establish a Datagramsocket object to receive or send datagrams, The Datagrampacket object is then used as a carrier for transmitting data. A program that usually has a fixed IP address and a fixed port Datagramsocket object is called a server because the Datagramsocket can proactively receive client data.
Before receiving data, the first or third constructor above should be used to generate a Datagrampacket object, giving the byte array to receive the data and its length. Then call Datagramsocket's receive () method to wait for the datagram to arrive, and receive () waits until the thread that called the method is blocked until a datagram is received. As shown in the following code:
- Create a Datagrampacket object that receives data
- Datagrampacket packet=new Datagrampacket (BUF, 256);
- Receiving datagrams
- Socket.receive (packet);
Before sending the data, call the second or fourth constructor to create the Datagrampacket object, at which point the byte array contains the data you want to send. In addition, the complete destination address, including the IP address and port number, is also given. The send data is implemented via the Datagramsocket Send () method, which is used to route datagrams based on the destination address of the datagram. As shown in the following code:
- Create a Datagrampacket object that sends data
- Datagrampacket packet = new Datagrampacket (buf, length, address, port);
- Send Datagrams
- Socket.send (packet);
When you use Datagrampacket to receive data, you feel that datagrampacket is too cumbersome to design. Developers only care about how much data the datagrampacket can put, and whether Datagrampacket uses a byte array to store the data at all. However, when Java requires the creation of a datagrampacket to receive data, an empty byte array must be passed in, and the length of the array determines how much data the datagrampacket can put, which actually exposes the implementation details of the Datagrampacket. Then Datagrampacket provides a GetData () method that returns an array of bytes encapsulated in the datagram packet object, which is more redundant-if the program needs to get an array of bytes encapsulated in Datagrampacket, Direct access to the byte array arguments passed to the Datagrampacket constructor, without calling the method.
When a Datagrampacket object is received by the server side (or the client), if you want to "feed back" some information to the sender of the datagram, but because the UDP protocol is non-connected, the receiver does not know who sent it to each datagram. However, the program can call Datagrampacket the following 3 methods to get the sender's IP address and port.
InetAddress getaddress (): When the program is ready to send this datagram, the method returns the IP address of the target machine for this datagram, and when the program has just received a datagram, the method returns the IP address of the sending host for that datagram.
int Getport (): When the program prepares to send this datagram, the method returns the port of the target machine for this datagram, and when the program has just received a datagram, the method returns the port of the sending host for that datagram.
SocketAddress getsocketaddress (): When the program is ready to send this datagram, the method returns the target socketaddress for this datagram, and when the program has just received a data chime, The method returns the socketaddress of the sending host for the datagram.
The return value of the Getsocketaddress () method is an SocketAddress object, which is actually an IP address and a port number. That is, the SocketAddress object encapsulates an InetAddress object and an integer representing the port, so using the SocketAddress object can represent both the IP address and the port.
17.4.2 sending and receiving data using Datagramsocket (2)
The following program uses Datagramsocket to implement the network communication of the server/client structure. The server side of this program uses loops 1000 times to read datagrams in Datagramsocket, and sends a message back to the sender of the datagram whenever the content is read. The server-side program code is as follows.
Program list: Codes\17\17.4\udpserver.java
- public class Udpserver
- {
- public static final int PORT = 30000;
- Define a maximum size of 4KB per datagram
- private static final int Data_len = 4096;
- Defines a byte array to receive network data
- byte[] inbuff = new Byte[data_len];
- Creates a Datagrampacket object that prepares to receive data in a specified byte array
- Private Datagrampacket Inpacket =
- New Datagrampacket (Inbuff, inbuff.length);
- Defines a Datagrampacket object for sending
- Private Datagrampacket Outpacket;
- Defines an array of strings that the server sends elements of the array
- string[] books = new string[]
- {
- "Crazy Java Handout",
- "Lightweight Java EE Enterprise Application Combat",
- "Crazy Android Handout",
- "Crazy Ajax Handout"
- };
- public void Init () throws IOException
- {
- Try
- Create a Datagramsocket object
- Datagramsocket socket = new Datagramsocket (PORT))
- {
- Using loops to receive data
- for (int i = 0; I < ; i++)
- {
- Read the data in the socket and read the data into an array in the Inpacket package
- Socket.receive (Inpacket);
- Determine if Inpacket.getdata () and Inbuff are the same array
- System.out.println (Inbuff = = Inpacket.getdata ());
- Output when the received content is converted to a string
- System.out.println (New String (Inbuff
- , 0, Inpacket.getlength ()));
- Take an element from a string array as the sending data
- byte[] senddata = books[i% 4].getbytes ();
- Sends data as a specified byte array, with the datagrampacket of the newly received
- Source SocketAddress is created as a target socketaddress datagrampacket
- outpacket = new Datagrampacket (SendData
- , Senddata.length, inpacket.getsocketaddress ());
- Send data
- Socket.send (Outpacket);
- }
- }
- }
- public static void Main (string[] args)
- Throws IOException
- {
- New Udpserver (). Init ();
- }
- }
The bold code in the above program is the key code to send and receive datagrampacket using Datagramsocket, which can receive data sent by 1000 clients.
Client program code is similar to this, the client uses the loop to continuously read the user's keyboard input, each time it reads the content entered by the user, encapsulates the content into a Datagrampacket datagram, and sends the datagram out The data in the Datagramsocket is then read into the receiving datagrampacket (which is actually read into the byte array encapsulated by the Datagrampacket). The client program code is as follows.
17.4.2 sending and receiving data using Datagramsocket (3)
Program list: Codes\17\17.4\udpclient.java
- public class UdpClient
- {
- Define the destination for sending datagrams
- public static final int dest_port = 30000;
- public static final String dest_ip = "127.0.0.1";
- Define a maximum size of 4KB per datagram
- private static final int Data_len = 4096;
- Defines a byte array to receive network data
- byte[] inbuff = new Byte[data_len];
- Creates a Datagrampacket object that prepares to receive data in a specified byte array
- Private Datagrampacket Inpacket =
- New Datagrampacket (Inbuff, inbuff.length);
- Defines a Datagrampacket object for sending
- Private Datagrampacket outpacket = null;
- public void Init () throws IOException
- {
- Try
- Create a client datagramsocket, using a random port
- Datagramsocket socket = new Datagramsocket ())
- {
- Initializes the sending Datagramsocket, which contains a byte array of length 0
- outpacket = new Datagrampacket (new Byte[0], 0
- , Inetaddress.getbyname (DEST_IP), dest_port);
- Creating a keyboard input stream
- Scanner scan = new Scanner (system.in);
- Constant reading of keyboard input
- while (Scan.hasnextline ())
- {
- Converts a string of keyboard input into a byte array
- byte[] buff = scan.nextline (). GetBytes ();
- Set byte data in Datagrampacket for sending
- Outpacket.setdata (Buff);
- Send Datagrams
- Socket.send (Outpacket);
- Reads the data in the socket, and the data is read in a byte array encapsulated by Inpacket
- Socket.receive (Inpacket);
- System.out.println (New String (Inbuff, 0
- , Inpacket.getlength ()));
- }
- }
- }
- public static void Main (string[] args)
- Throws IOException
- {
- New UdpClient (). Init ();
- }
- }
The bold code in the above program is also the key code to send and receive datagrampacket using Datagramsocket, which is basically similar to the server-side code. The only difference between client and server is that the server-side IP address and port are fixed, so the client can send the datagram directly to the server side, and the server side needs to determine the destination of the "feedback" datagram based on the datagram received.
Readers may find that when using Datagramsocket for network communication, there is no need for the server to save the state of each client, and the client sends the datagram to the server side, and it is possible to exit immediately. However, the server cannot know the status of the client regardless of whether the client exits.
When using the UDP protocol, it is more difficult to have one client send chat messages forwarded to all other clients, consider using the set collection on the server side to hold all client information, and each time a client's datagram is received, The program checks whether the source socketaddress of the datagram is in the set collection, and if not, adds the socketaddress to the set collection. This also involves a problem: Some clients may send a datagram permanently after exiting the program, but the server side also saves the client's socketaddress in the Set collection ... In short, this way needs to deal with more problems, programming more cumbersome. Fortunately, Java provides the MulticastSocket class for the UDP protocol, which makes it easy to implement multipoint broadcasts.
UDP protocol Basics (turn from crazy Java handouts)