Network programming
summary
- Under the network communication protocol, programs running on different computers can transmit data
Three elements
- IP address: the address of the equipment in the network, which is the unique identification;
- Port: the unique identification of the application in the device;
- Protocol: the rules of data transmission in the network. The common protocols are UDP protocol and TCP protocol.
- UDP protocol
- User datagram protocol
- UDP is a connectionless communication protocol with high speed and size limit. It can send up to 64k at a time. The data is unsafe and easy to lose data.
- TCP protocol
- Transmission control protocol
- TCP protocol is a connection oriented communication protocol with slow speed, no size limit and data security.
- UDP protocol
IP address
Common commands:
- ipconfig: view the local IP address
- ping IP address: check whether the network is connected
Special IP address:
- 127.0.0.1: it is the outgoing address, also known as the local loopback address. It can represent the IP address of the machine. It is generally used for testing
InetAddress
- static InetAddress getByName(String host): determines the IP address of the host name. The host name can be either a machine name or an IP address
- String getHostName(): get the host name of this IP address
- String getHostAddress(): returns the IP address string in the text display
import java.net.InetAddress; import java.net.UnknownHostException; public class InetAddressTest { public static void main(String[] args) throws UnknownHostException { InetAddress address = InetAddress.getByName("I can fly, too"); String hostName = address.getHostName(); System.out.println("The host name is:"+hostName); String hostAddress = address.getHostAddress(); System.out.println("IP For:"+hostAddress); } }
port
Port number: an integer represented by two bytes. Its value range is 065535. The port number between 01023 is used for some well-known network services or applications. We can use the port number above 1024 by ourselves. A port number can only be used by one application.
UDP send data
Take chestnuts: send gifts
- Find a rookie station ----------- create a DatagramSocket object at the sending end
- Package gift ----------- create data and package the data (datagram packet)
- Send package by post ------------- call the method of DatagramSocket object to send data
- Pay and leave ---------- release resources
import java.io.IOException; import java.net.*; public class ClientTest { public static void main(String[] args) throws IOException { //Find a post station DatagramSocket ds = new DatagramSocket(); //Pack gifts String s = "A gift for a loved one"; byte[] bytes = s.getBytes(); InetAddress address = InetAddress.getByName("127.0.0.1"); int port = 8888; DatagramPacket dp = new DatagramPacket(bytes,bytes.length,address,port); //Send package ds.send(dp); //Pay and leave ds.close(); } }
UDP receive data
- Find receiving point ------------ create DatagramSocket object of receiving end
- Find a new box ------------ create a box to receive data
- Receive the gift and put it back in the box ------------ call the datagram socket method to receive the data and put it into the box
- Get gifts from the box ------------- analyze the data package and display the data on the console
- Take and leave ------------- release resources
import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.SocketException; public class ServerTest { public static void main(String[] args) throws IOException { //Find the receiving point. The parameter indicates that the receiving end receives data from port 8888 DatagramSocket ds = new DatagramSocket(8888); //Create a new box byte[] bytes = new byte[1024]; DatagramPacket dp = new DatagramPacket(bytes,bytes.length); //Put the gift in the new box ds.receive(dp); //Get a gift from a new box //byte[] data = dp.getData(); int length = dp.getLength(); System.out.println(new String(bytes,0,length)); //Take it and leave ds.close(); } }
UDP communication program exercise
Implement the program according to the following requirements
- UDP sending data: the data comes from the keyboard input until the input data is see you later, and the sending data ends
- UDP receiving data: because the receiving end does not know when the sending end will stop sending, it adopts dead loop receiving
Sender import java.io.IOException; import java.net.*; import java.util.Scanner; public class ClientTest { public static void main(String[] args) throws IOException { Scanner sc = new Scanner(System.in); DatagramSocket ds = new DatagramSocket(); while (true) { String s = sc.nextLine(); if(s.equals("see you later")){ break; } byte[] bytes = s.getBytes(); InetAddress address = InetAddress.getByName("127.0.0.1"); int port = 8888; DatagramPacket dp = new DatagramPacket(bytes,bytes.length,address,port); ds.send(dp); } ds.close(); } } receiving end import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; public class ServerTest { public static void main(String[] args) throws IOException { DatagramSocket ds = new DatagramSocket(8888); while (true) { byte[] bytes = new byte[1024]; DatagramPacket dp = new DatagramPacket(bytes,bytes.length); ds.receive(dp); byte[] data = dp.getData(); int length = dp.getLength(); System.out.println(new String(data,0,length)); } //ds.close(); } }
Three communication modes of UDP
- Unicast: point-to-point communication
- Multicast: a sender sends data to a group of receivers through a router
- Broadcast: a sender sends data to all receivers in the LAN through the router
UDP communication multicast
Multicast address: 224.0.0.0239.255.255.255, of which 224.0.0.0224.0.0.255 bits are reserved multicast addresses
Sender import java.io.IOException; import java.net.*; public class clientTest { public static void main(String[] args) throws IOException { DatagramSocket ds = new DatagramSocket(); String s = "hello Multicast "; byte[] bytes = s.getBytes(); InetAddress address = InetAddress.getByName("224.0.2.0"); int port = 8888; DatagramPacket dp = new DatagramPacket(bytes,bytes.length,address,port); ds.send(dp); ds.close(); } } receiving end import java.io.IOException; import java.net.DatagramPacket; import java.net.InetAddress; import java.net.MulticastSocket; public class ServerTest { public static void main(String[] args) throws IOException { MulticastSocket ms = new MulticastSocket(8888); DatagramPacket dp = new DatagramPacket(new byte[1024],1024); //Bind the current computer to a multicast address to add it to this group ms.joinGroup(InetAddress.getByName("224.0.2.0")); ms.receive(dp); byte[] data = dp.getData(); int length = dp.getLength(); System.out.println(new String(data,0,length)); ms.close(); } }
UDP communication broadcast
Broadcast address: 255.255.255.255
Sender import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; public class ClientTest { public static void main(String[] args) throws IOException { DatagramSocket ds = new DatagramSocket(); String s = "Shh!"; byte[] bytes = s.getBytes(); InetAddress address = InetAddress.getByName("255.255.255.255"); int port = 8888; DatagramPacket dp = new DatagramPacket(bytes,bytes.length,address,port); ds.send(dp); ds.close(); } } receiving end import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; public class ServerTest { public static void main(String[] args) throws IOException { DatagramSocket ds = new DatagramSocket(8888); DatagramPacket dp = new DatagramPacket(new byte[1024],1024); ds.receive(dp); byte[] data = dp.getData(); int length = dp.getLength(); System.out.println(new String(data,0,length)); ds.close(); } }
TCP communication principle
TCP communication protocol is a reliable network protocol. It establishes a Socket object at both ends of the communication;
Before communication, ensure that the connection has been established and generate IO flow through Socket for network communication.
Steps to send data via TCP
- Create the Socket object (Socket) of the client and connect the Socket(String host,int port) with the specified server
- Get the output stream and write data OutputStream getOutputStream()
- Release resource void close()
import java.io.IOException; import java.io.OutputStream; import java.net.Socket; public class ClientTest { public static void main(String[] args) throws IOException { //Create a Socket object Socket socket = new Socket("127.0.0.1",8888); //Get an IO stream and start writing data OutputStream os = socket.getOutputStream(); os.write("hello".getBytes()); //Release resources os.close(); socket.close(); } }
TCP receive data
- Create a server-side Socket object (ServerSocket) ServerSocket(int port)
- Listen to the client connection and return a Socket object Socket accept()
- Get the input stream, read the data, and display the data on the console InputStream getInputStream()
- Release resource void close()
import java.io.IOException; import java.io.InputStream; import java.net.ServerSocket; import java.net.Socket; public class ServerTest { public static void main(String[] args) throws IOException { //Create Socket object ServerSocket ss = new ServerSocket(8888); //Waiting for client connection Socket accept = ss.accept(); //Get input stream object InputStream is = accept.getInputStream(); int b; while ((b = is.read()) != -1){ System.out.println((char) b); } //Release resources is.close(); ss.close(); } }
be careful
- The accept method is blocked, and its function is to wait for the client to connect;
- The client creates an object and connects to the server. At this time, the connection with the server is guaranteed through the three-time handshake protocol;
- For the client, it is written out, so it is an output stream; For the server, it reads in, so it is an input stream;
- The read method is also blocked;
- When closing the flow, there is also an action for the web server to write the end flag;
- Disconnect for the last time, and ensure the termination of the connection through the four wave agreement;
Three this handshake
Four waves
TCP exercise 1
- Client: send data and receive server feedback
- Server: receive data and give feedback
Sender import java.io.*; import java.net.Socket; public class ClientTest { public static void main(String[] args) throws IOException { Socket socket = new Socket("127.0.0.1",8888); OutputStream os = socket.getOutputStream(); os.write("hello".getBytes()); //os.close; If the flow is closed here, the whole socket will be unusable socket.shutdownOutput();//Close the output stream tightly and write an end tag, which has no effect on the socket // InputStream is = socket.getInputStream(); // int b; // while ((b = is.read()) != -1){ // System.out.println((char) b); // } // is.close(); BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); String line; while ((line = br.readLine()) != null){ System.out.println(line); } br.close(); os.close(); socket.close(); } } receiving end import java.io.*; import java.net.ServerSocket; import java.net.Socket; public class ServerTest { public static void main(String[] args) throws IOException { ServerSocket ss = new ServerSocket(8888); Socket accept = ss.accept(); InputStream is = accept.getInputStream(); int b; while ((b = is.read()) != -1){ System.out.println((char) b); } // OutputStream os = accept.getOutputStream(); // os.write("who are you?" getBytes()); // os.close(); BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(accept.getOutputStream())); bw.write("who are you?"); bw.newLine(); bw.flush(); bw.close(); is.close(); accept.close(); ss.close(); } }
TCP exercise 2
- Client: upload local files to the server and receive feedback from the server
- Server: receive the files uploaded by the client and give feedback after uploading.
client import java.io.*; import java.net.Socket; public class ClientTest { public static void main(String[] args) throws IOException { Socket socket = new Socket("127.0.0.1",8888); //Local stream, which is used to read local files BufferedInputStream bis = new BufferedInputStream(new FileInputStream("day24\\1.gif")); //Write to server, stream in network OutputStream os = socket.getOutputStream(); BufferedOutputStream bos = new BufferedOutputStream(os); int b; while ((b = bis.read())!=-1){ bos.write(b);//Write to the server through the network } //Give the server an end tag socket.shutdownOutput(); BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); String line; while ((line = br.readLine())!=null){ System.out.println(line); } bis.close(); socket.close(); } } Server side import java.io.*; import java.net.ServerSocket; import java.net.Socket; public class ServerTest { public static void main(String[] args) throws IOException { ServerSocket ss = new ServerSocket(8888); Socket accept = ss.accept(); //The stream in the network reads data from the client BufferedInputStream bis = new BufferedInputStream(accept.getInputStream()); //The local IO stream writes the data locally to realize permanent storage BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("day24\\2.gif")); int b; while ((b = bis.read())!=-1){ bos.write(b); } BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(accept.getOutputStream())); bw.write("Upload successful"); bw.newLine(); bw.flush(); bos.close(); accept.close(); ss.close(); } }
UUID
This class can generate unique and random strings;
import java.util.UUID; public class UUIDTest { public static void main(String[] args) { UUID uuid = UUID.randomUUID(); String s = uuid.toString().replace("-",""); System.out.println(s); } }
Optimize exercise 2 with loops and UUID s
Change server side only import java.io.*; import java.net.ServerSocket; import java.net.Socket; import java.util.UUID; public class ServerTest { public static void main(String[] args) throws IOException { ServerSocket ss = new ServerSocket(8888); Socket accept = null; while (true) { accept = ss.accept(); //The stream in the network reads data from the client BufferedInputStream bis = new BufferedInputStream(accept.getInputStream()); //The local IO stream writes the data locally to realize permanent storage BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("day24\\"+ UUID.randomUUID().toString().replace("-","")+".gif")); int b; while ((b = bis.read())!=-1){ bos.write(b); } BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(accept.getOutputStream())); bw.write("Upload successful"); bw.newLine(); bw.flush(); bos.close(); accept.close(); } //ss.close(); }
Multi thread + thread pool further optimization exercise 2
Thread: import java.io.*; import java.net.Socket; import java.util.UUID; public class ThreadSockt implements Runnable { private Socket accept; public ThreadSockt(Socket accept) { this.accept = accept; } @Override public void run() { BufferedOutputStream bos = null; try { //The stream in the network reads data from the client BufferedInputStream bis = new BufferedInputStream(accept.getInputStream()); //The local IO stream writes the data locally to realize permanent storage bos = new BufferedOutputStream(new FileOutputStream("day24\\"+ UUID.randomUUID().toString().replace("-","")+".gif")); int b; while ((b = bis.read())!=-1){ bos.write(b); } BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(accept.getOutputStream())); bw.write("Upload successful"); bw.newLine(); bw.flush(); } catch (IOException e) { e.printStackTrace(); }finally { if (bos !=null){ try { bos.close(); } catch (IOException e) { e.printStackTrace(); } } if (accept != null){ try { accept.close(); } catch (IOException e) { e.printStackTrace(); } } } } } Only improve the server side import java.io.*; import java.net.ServerSocket; import java.net.Socket; import java.util.UUID; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.Executors; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; public class ServerTest { public static void main(String[] args) throws IOException { ServerSocket ss = new ServerSocket(8888); ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(3,8,60, TimeUnit.SECONDS,new ArrayBlockingQueue<>(5), Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy()); Socket accept = null; while (true) { accept = ss.accept(); ThreadSockt ts = new ThreadSockt(accept); //new Thread(ts).start(); threadPoolExecutor.submit(ts); } //ss.close(); } }