Network programming
What is network programming?
- Network programming allows programs to interact with programs in other devices on the network.
Basic mode of network communication
- There are two common communication modes: client server (CS) and Browser/Server(BS)
Three elements of network communication
Three elements overview, element 1: IP address
####Three key elements of network programming
IP address: the address of the device in the network. It is a 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.
IP address
- IP (Internet Protocol): the full name is "Internet protocol address", which is the only sign assigned to Internet devices.
- Common IP classifications are IPv4 and IPv6
####IP address form:
- Public address, and private address (for LAN use).
- 192.168. At the beginning is the common LAN address, ranging from 192.168.0.0 – 192.168.255.255, which is specially used within the organization.
####Common IP commands:
-
ipconfig: view the local IP address
-
ping IP address: check whether the network is connected
####Special IP address:
- Local IP: 127.0.0.1 or localhost: it is called loopback address or local loopback address. It will only find the current local machine.
summary
- Talk about at least a few elements of network communication
IP, port and protocol.
What do IP addresses do? There are several specific types
Locate the devices on the network, including IPv4 and IPv6 - How to view the local IP address and whether to communicate with each other
ipconfig
ping 192.168.10.23
Who is the native IP?
127.0.0.1 or localhost
###IP address operation class InetAddress
Use of InetAddress
- This class represents an Internet Protocol (IP) address.
The InetAddress API is as follows
name | explain |
---|---|
public static InetAddress getLocalHost() | Return the address object of this host |
public static InetAddress getByName(String host) | Get the IP address object of the specified host. The parameters are domain name or IP address |
public String getHostName() | Gets the host name of this IP address |
public String getHostAddress() | Return IP address string |
public boolean isReachable(int timeout) | Connect to the host corresponding to the IP address within the specified milliseconds, and the connection returns true |
- Who is the representative class of IP address?
InetAddress class - How to get native IP objects
public static InetAddress getLocalHost() - How to judge whether it is interworking with the IP address object?
public boolean isReachable(int timeout)
package com.itheima.d1_inetAddress; import java.net.InetAddress; import java.net.UnknownHostException; /** Objective: InetAddress class overview (understand) An object of this class represents an IP address object. InetAddress Class member method: static InetAddress getLocalHost() * Get the local host IP address object. static InetAddress getByName(String host) * Obtain the corresponding IP address object according to the IP address string or host name. String getHostName() * Get the host name. String getHostAddress() * Get the IP address string. */ public class InetAddressDemo1 { public static void main(String[] args) throws Exception { // 1. Get the local address object. InetAddress ip1=InetAddress.getLocalHost(); System.out.println(ip1); System.out.println(ip1.getHostName()); System.out.println(ip1.getHostAddress()); // 2. Get domain name ip object InetAddress ip2=InetAddress.getByName("www.baidu.com"); System.out.println(ip2.getHostName()); System.out.println(ip2.getHostAddress()); // 3. Obtain the public IP object. InetAddress ip3=InetAddress.getByName("14.215.177.39"); System.out.println(ip3.getHostName()); System.out.println(ip3.getHostAddress()); // 4. Judge whether it can be connected: test whether it can be connected before Ping 5S System.out.println(ip3.isReachable(5000)); } } //DESKTOP-HMRDQCV/192.168.10.109 // DESKTOP-HMRDQCV // 192.168.10.109 // www.baidu.com // 14.215.177.39 // 14.215.177.39 // 14.215.177.39 // true
###Element 2: port number
Port number
- Port number: identifies the process (program) running on the computer equipment. It is specified as a 16 bit binary, ranging from 0 to 65535.
port type
-
Well known ports: 0 ~ 1023, occupied by well-known applications defined in advance (e.g. HTTP occupies 80, FTP occupies 21)
-
Registration port: 1024 ~ 49151, which is assigned to user processes or some applications. (for example, Tomcat occupies 8080 and MySQL occupies 3306)
-
Dynamic port: 49152 to 65535. It is called dynamic port because it is generally dynamically allocated instead of a fixed process.
be careful
- The program developed by ourselves selects the registration port, and the port numbers of two programs cannot be the same in a device, otherwise an error will occur.
- What is the function of port number?
Uniquely identifies the process (program) running on the computer device - Can two applications have the same port number in a device? Why?
No, if the same, a port conflict error will appear.
###Element 3: agreement
communication protocol
- The rules for connecting and communicating data are called network communication protocols
####There are two sets of reference models for network communication protocols
- OSI reference model: World interconnection protocol standard and global communication specification. Because this model is too idealized, it can not be widely popularized on the Internet.
- TCP/IP reference model (or TCP/IP Protocol): a de facto international standard.
OSI reference model | TCP/IP reference model | Corresponding to each layer | Operation Oriented |
---|---|---|---|
application layer | application layer | HTTP,FTP,DNS,SMTP... | Applications need to pay attention to: browser, mailbox. Programmers usually develop at this level |
Presentation layer | |||
Session layer | |||
Transport layer | Transport layer | TCP,UDP... | Select the TCP and UDP protocols to use |
network layer | network layer | IP,ICMP... | Encapsulate the source and target IP for path selection |
data link layer | Data link layer + physical | Physical addressing, bitstream | Transmission in physical device |
physical layer |
####Two common protocols of transport layer
- TCP(Transmission Control Protocol): Transmission Control Protocol
- UDP(User Datagram Protocol): User Datagram Protocol
TCP protocol features
-
Using TCP protocol, both parties must establish a connection first. It is a reliable connection oriented communication protocol.
-
Before transmission, the connection is established by "three handshakes", so it is reliable.
-
A large amount of data can be transmitted in the connection.
-
The connection and sending data need to be confirmed, and after the transmission is completed, the established connection needs to be released, so the communication efficiency is low.
####TCP protocol communication scenario
- For example, there are high requirements for the downloading of financial data and scenarios.
UDP protocol:
-
UDP is a connectionless and unreliable transmission protocol.
-
Encapsulate the data source IP, destination IP and port into data packets without establishing a connection
-
The size of each packet is limited to 64KB
-
Whether the sending party is ready or not, the receiving party does not confirm the receipt, so it is unreliable
-
It can broadcast and send, and there is no need to release resources at the end of sending data, with low overhead and high speed.
UDP protocol communication scenario
- Voice call, video conversation, etc.
summary
What is the communication protocol?
In computer networks, the rules for connecting and communicating data are called network communication protocols.
2. What are the characteristics of TCP communication protocol?
It is a reliable connection oriented communication protocol.
Before transmission, the connection is established by "three times handshake", and the point-to-point communication is reliable.
A large amount of data can be transmitted in the connection.
Low communication efficiency.
3. What are the characteristics of UDP protocol
User datagram protocol
UDP is a communication protocol for connectionless and unreliable transmission.
Fast speed, size limit, sending 64K at most at a time, unsafe data and easy to lose data.
##UDP communication - quick start
UDP communication: getting started
####Characteristics of UDP protocol
- UDP is a connectionless and unreliable transmission protocol.
- Encapsulate the data source IP, destination IP and port as well as data into data packets. The size is limited to 64KB and can be sent directly.
####Datagram packet: packet object (leek plate)
constructor | explain |
---|---|
public DatagramPacket(byte[] buf, int length, InetAddress address, int port) | Create the sending end packet object buf: the content to be sent, byte array length: the byte length of the content to be sent, address: the IP address of the receiving end, object port: the port number of the receiving end |
public DatagramPacket(byte[] buf, int length) | Create the data packet object buf of the receiving end: used to store the received content. Length: the length of the content that can be received |
####Common methods of datagram packet
method | explain |
---|---|
public int getLength() | Get the number of bytes actually received |
####Datagram socket: sender and receiver objects (person)
constructor | explain |
---|---|
public DatagramSocket() | Create a Socket object at the sending end, and the system will randomly assign a port number. |
public DatagramSocket(int port) | Create the Socket object of the receiving end and specify the port number |
####DatagramSocket class member method
method | explain |
---|---|
public void send(DatagramPacket dp) | Send packet |
public void receive(DatagramPacket p) | Receive packet |
####UDP communication is used to realize: sending and receiving messages
Requirements: client implementation steps
The person who creates DatagramSocket object (sender object) and throws leeks
Create a datagram packet object to encapsulate the data (packet object) to be sent
Use the send method of the datagram socket object to pass in the datagram packet object and start throwing leeks
Release resources
package com.itheima.d2_udp1; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.net.SocketException; /** * Sender */ public class ClientDemo1 { public static void main(String[] args) throws Exception { System.out.println("==============Client startup=================="); //1. Create a sending object. The sending end has its own default port number DatagramSocket socket=new DatagramSocket(); //2. Create a packet object to encapsulate the object /** *public DatagramPacket(byte buf[], int length, * InetAddress address, int port) * Parameter 1: encapsulate the data to be sent (leek), the content to be sent, and the byte array * length: Byte length of content to send * address: Host IP address object of the server * port: Port number of receiving end */ byte[]buffer="I am a leek".getBytes(); DatagramPacket packet=new DatagramPacket(buffer, buffer.length,InetAddress.getLocalHost(),8888); //3. Send data out socket.send(packet); socket.close(); } }
package com.itheima.d2_udp1; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.SocketException; /** * receiving end */ public class ServerDemo2 { public static void main(String[] args) throws IOException { System.out.println("==============Server start=================="); //1. Create receiver object: registered port (person) DatagramSocket socket=new DatagramSocket(8888); //2. Create a packet object to accept leek dishes byte[] buffer=new byte[1024*64]; DatagramPacket packet=new DatagramPacket(buffer, buffer.length); //3. Wait for the data to be received socket.receive(packet); //4. Just take out the data //Take as much as you pour int len=packet.getLength(); String rs=new String(buffer,0,len); System.out.println("I got it"+rs); //Get the ip and port of the sender String ip=packet.getSocketAddress().toString(); System.out.println("Address of the opposite party:"+ip); int port=packet.getPort(); System.out.println("Opposite port:"+port); socket.close(); } }
- Which is the object of UDP sender and receiver?
- public DatagramSocket(): creates the Socket object of the sender
- Public datagram Socket (int port): create the Socket object of the receiving end
- What is the packet object?
- DatagramPacket
- How to send and receive data packets
- The following methods of using datagram socket:
- Public void send (datagram packet DP): send packets
- Public void receive (datagram packet DP): receive data packets
UDP communication: multiple sending and multiple receiving
Using UDP communication to realize: multiple sending and multiple receiving messages
demand
Use UDP communication to develop the receiver and sender.
analysis
The sender can always send messages.
The receiving end can continuously receive the message display of multiple sending ends.
If the sender enters exit, the sender ends the program.
The sender can send data repeatedly
Requirements: client implementation steps
The person who creates DatagramSocket object (sender object) and throws leeks
Use the while loop to continuously receive the user's data input. If the user enters exit, exit the program
If the user does not enter exit, encapsulate the data into a datagram packet leek dish
Use the send method of DatagramSocket object to send the packet object and start throwing leeks
Release resources
The receiving end can receive data repeatedly
Requirements: receiver implementation steps
Create a DatagramSocket object and specify the port (receiver object) to which the leek is connected
Create datagram packet object to receive data (packet object) leek plate
Use the while loop to continue step 4
Use the receive method of datagram socket object to pass in datagram packet object and start receiving leeks
package com.itheima.d3_udp2; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.util.Scanner; /** * Multiple sending and multiple receiving at the sender (repeated) */ public class ClientDemo1 { public static void main(String[] args) throws Exception { System.out.println("==============Client startup=================="); //1. Create a sending object. The sending end has its own default port number DatagramSocket socket=new DatagramSocket(777); //2. Create a packet object to encapsulate the object Scanner sc=new Scanner(System.in); while (true) { System.out.println("Please"); String msg=sc.nextLine(); if("exie".equals(msg)){ System.out.println("Offline success"); socket.close(); } byte[] buffer = msg.getBytes(); DatagramPacket packet = new DatagramPacket(buffer, buffer.length, InetAddress.getLocalHost(), 8888); //3. Send data out socket.send(packet); } } }
package com.itheima.d3_udp2; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; /** * receiving end */ public class ServerDemo2 { public static void main(String[] args) throws IOException { System.out.println("==============Server start=================="); //1. Create receiver object: registered port (person) DatagramSocket socket=new DatagramSocket(8888); //2. Create a packet object to accept leek dishes byte[] buffer=new byte[1024*64]; DatagramPacket packet=new DatagramPacket(buffer, buffer.length); while (true) { //3. Wait for the data to be received socket.receive(packet); //4. Just take out the data //Take as much as you pour int len = packet.getLength(); String rs = new String(buffer, 0, len); System.out.println("Received from:" + packet.getAddress() + ",The opposite port is" + packet.getPort() + "News of" + rs); } } }
-
Why can the receiving end of UDP receive many messages from the sending end?
The receiver is only responsible for receiving packets, regardless of which sender's packet
##UDP communication - broadcast and multicast
Three communication modes of UDP
- Unicast: communication between a single host and a single host.
- Broadcast: the current host communicates with all hosts in the network.
- Multicast: the communication between the current host and a selected group of hosts.
How to implement UDP broadcast
- Use broadcast address: 255.255.255.255
- Specific operation:
- The destination of the packet sent by the sender is the broadcast address and the port is specified. (255.255.255.255 , 9999)
- The programs of other hosts in the network segment where this machine is located can receive messages as long as they register the corresponding port. (9999)
package com.itheima.d4_udp3_broadcast; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.util.Scanner; /** * Multiple sending and multiple receiving at the sender (repeated) */ public class ClientDemo1 { public static void main(String[] args) throws Exception { System.out.println("==============Client startup=================="); //1. Create a sending object. The sending end has its own default port number DatagramSocket socket=new DatagramSocket(); //2. Create a packet object to encapsulate the object Scanner sc=new Scanner(System.in); while (true) { System.out.println("Please"); String msg=sc.nextLine(); if("exie".equals(msg)){ System.out.println("Offline success"); socket.close(); return; } byte[] buffer = msg.getBytes(); DatagramPacket packet = new DatagramPacket(buffer, buffer.length, InetAddress.getByName("255.255.255.255"), 9999); //3. Send data out socket.send(packet); } } }
package com.itheima.d4_udp3_broadcast; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; /** * receiving end */ public class ServerDemo2 { public static void main(String[] args) throws IOException { System.out.println("==============Server start=================="); //1. Create receiver object: registered port (person) DatagramSocket socket=new DatagramSocket(9999); //2. Create a packet object to accept leek dishes byte[] buffer=new byte[1024*64]; DatagramPacket packet=new DatagramPacket(buffer, buffer.length); while (true) { //3. Wait for the data to be received socket.receive(packet); //4. Take out the data //Take as much as you pour int len = packet.getLength(); String rs = new String(buffer, 0, len); System.out.println("Received from:" + packet.getAddress() + ",The opposite port is" + packet.getPort() + "News of" + rs); } } }
How to implement multicast with UDP
- Use multicast address: 224.0.0.0 ~ 239.255.255.255
- Specific operation:
- The destination of the data packet at the sending end is multicast IP (for example: 224.0.1.1, port: 9999)
- The receiving end must bind the multicast IP(224.0.1.1) and register the destination port 9999 of the sending end, so that the multicast message can be received.
- MulticastSocket, a subclass of datagram socket, can bind multicast IP at the receiving end.
package com.itheima.d5_udp4_multicast; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.util.Scanner; /** * Multiple sending and multiple receiving at the sender (repeated) */ public class ClientDemo1 { public static void main(String[] args) throws Exception { System.out.println("==============Client startup=================="); //1. Create a sending object. The sending end has its own default port number DatagramSocket socket=new DatagramSocket(); //2. Create a packet object to encapsulate the object Scanner sc=new Scanner(System.in); while (true) { System.out.println("Please"); String msg=sc.nextLine(); if("exie".equals(msg)){ System.out.println("Offline success"); socket.close(); return; } byte[] buffer = msg.getBytes(); DatagramPacket packet = new DatagramPacket(buffer, buffer.length, InetAddress.getByName("224.0.1.1"), 9999); //3. Send data out socket.send(packet); } } }
package com.itheima.d5_udp4_multicast; import java.io.IOException; import java.net.*; /** * receiving end */ public class ServerDemo2 { public static void main(String[] args) throws IOException { System.out.println("==============Server start=================="); //1. Create receiver object: registered port (person) MulticastSocket socket=new MulticastSocket(9999); //Add the current receiver to a multicast group: bind the multicast IP of the corresponding multicast message //socket.joinGroup(InetAddress.getByName("224.0.1.1")); socket.joinGroup(new InetSocketAddress(InetAddress.getByName("224.0.1.1"),9999) ,NetworkInterface.getByInetAddress(InetAddress.getLocalHost())); //2. Create a packet object to accept leek dishes byte[] buffer=new byte[1024*64]; DatagramPacket packet=new DatagramPacket(buffer, buffer.length); while (true) { //3. Wait for the data to be received socket.receive(packet); //4. Just take out the data //Take as much as you pour int len = packet.getLength(); String rs = new String(buffer, 0, len); System.out.println("Received from:" + packet.getAddress() + ",The opposite port is" + packet.getPort() + "News of" + rs); } } }
- How to realize broadcasting and how to operate it?
The destination IP of the sender uses the broadcast IP: 255.255.255.255 9999.
Other hosts in the network segment correspond to the port (9999) to receive messages. - How to implement multicast and how to operate it?
The multicast destination uses IP.
Other hosts in the network segment can receive messages after registering the multicast IP and the corresponding port.
##TCP communication - quick start
Writing client code
TCP protocol review
- TCP is a connection oriented, secure and reliable data transmission protocol
- Before transmission, the "three-time handshake" mode is adopted for point-to-point communication, which is reliable
- Large amount of data can be transmitted during connection
####Socket
constructor | explain |
---|---|
public Socket(String host , int port) | Create a Socket object at the sending end to connect with the server. The parameters are the ip and port of the server program. |
####Socket class member method
method | explain |
---|---|
OutputStream getOutputStream() | Get byte output stream object |
InputStream getInputStream() | Get byte input stream object |
Send message to client
Requirements: client implementation steps
Create the Socket object of the client and request the connection with the server.
Use socket object to call getOutputStream() method to get byte output stream.
Use byte output stream to send data.
Free resources: close the socket pipe.
package com.itheima.d6_socket; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.PrintStream; import java.net.Socket; /** * Objective: to complete the client development of Socket network programming entry case, one sending and one receiving */ public class ClientDemo1 { public static void main(String[] args){ try { System.out.println("==============Client started successfully==================="); //1. Create a Socket communication pipeline to request the connection of the server //public Socket(String host , int port) //Parameter 1: Ip address of the server parameter 2: port of the server Socket socket=new Socket("127.0.0.1",7777); //2. Get a byte output stream from the socket communication pipeline, which is responsible for sending data OutputStream os=socket.getOutputStream(); //3. Package the low-level byte stream into a print stream PrintStream ps=new PrintStream(os); //4. Send message ps.println("I'm a beautiful woman"); ps.flush(); //close resource //socket.close(); } catch (IOException e) { e.printStackTrace(); } } }
- Who is the representative class of TCP communication client?
- Socket class
- public Socket(String host , int port)
- How TCP communication uses Socket pipes to send and receive data.
- OutputStream getOutputStream(): get byte output stream object (send)
- InputStream getInputStream(): get byte input stream object (receive)
###Write server code and principle analysis
ServerSocket (server)
constructor | explain |
---|---|
public ServerSocket(int port) | Register server port |
ServerSocket class member method
method | explain |
---|---|
public Socket accept() | Wait for the Socket communication connection of the receiving client to succeed. Return the Socket object to establish end-to-end communication with the client |
The server realizes receiving messages
Requirements: server implementation steps
Create a ServerSocket object and register the server port.
Call the accept() method of the ServerSocket object, wait for the client to connect, and get the Socket pipe object.
Call getInputStream() method through Socket object to get byte input stream and complete data reception.
Free resources: close socket pipe
package com.itheima.d6_socket; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.ServerSocket; import java.net.Socket; /** * Objective: to develop a server for Socket network programming entry code to accept messages */ public class ServerDemo2 { public static void main(String[] args) { try { System.out.println("==============The server is started successfully==================="); //1. Registered port ServerSocket serverSocket=new ServerSocket(7777); //2. The accept method must be called to wait for receiving the Socket connection request from the client and establish the Socket communication pipeline Socket socket=serverSocket.accept(); //3. Get a byte input stream from the socket communication pipeline InputStream is=socket.getInputStream(); //4. Wrap the byte input stream into a buffered character input stream for message reception BufferedReader br=new BufferedReader(new InputStreamReader(is)); //5. Read the message by line String msg; if ((msg=br.readLine())!=null){ System.out.println(socket.getRemoteSocketAddress()+":Said:"+msg); } } catch (IOException e) { e.printStackTrace(); } } }
- Representative class for TCP communication server?
ServerSocket class, register port.
Call the accept() method to block the client connection waiting to receive. Get the Socket object. - The basic principle of TCP communication?
The client should receive as it sends.
If the client has no message, the server will enter blocking waiting.
When one Socket is closed or abnormal, the other Socket will also fail or make an error.
##TCP communication - multiple messages
Using TCP communication to realize: multiple sending and multiple receiving messages
Requirements: use TCP communication mode to realize: multiple sending and multiple receiving messages.
Specific requirements:
You can use an endless loop to control the server to continue waiting for the next message after receiving the message.
The client can also use an endless loop to wait for the user to continuously input messages.
Once the client enters exit, it closes the client program and releases resources.
- This case realizes multiple sending and multiple receiving. Can I receive messages from multiple clients at the same time?
No.
Because the server now has only one thread and can only communicate with one client.
package com.itheima.d7_socket2; import java.io.IOException; import java.io.OutputStream; import java.io.PrintStream; import java.net.Socket; import java.util.Scanner; /** * Objective: to realize multiple sending and multiple receiving */ public class ClientDemo1 { public static void main(String[] args){ try { System.out.println("==============Client started successfully==================="); //1. Create a Socket communication pipeline to request the connection of the server //public Socket(String host , int port) //Parameter 1: Ip address of the server parameter 2: port of the server Socket socket=new Socket("127.0.0.1",7777); //2. Get a byte output stream from the socket communication pipeline, which is responsible for sending data OutputStream os=socket.getOutputStream(); //3. Package the low-level byte stream into a print stream PrintStream ps=new PrintStream(os); Scanner sc=new Scanner(System.in); while(true){ System.out.println("Please"); String msg= sc.nextLine(); //4. Send message ps.println(""); ps.flush(); } //close resource //socket.close(); } catch (IOException e) { e.printStackTrace(); } } }
package com.itheima.d7_socket2; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.ServerSocket; import java.net.Socket; /** * Objective: to develop a server for Socket network programming entry code to accept messages */ public class ServerDemo2 { public static void main(String[] args) { try { System.out.println("==============The server is started successfully==================="); //1. Registered port ServerSocket serverSocket=new ServerSocket(7777); //2. The accept method must be called to wait for receiving the Socket connection request from the client and establish the Socket communication pipeline Socket socket=serverSocket.accept(); //3. Get a byte input stream from the socket communication pipeline InputStream is=socket.getInputStream(); //4. Wrap the byte input stream into a buffered character input stream for message reception BufferedReader br=new BufferedReader(new InputStreamReader(is)); //5. Read the message by line String msg; while ((msg=br.readLine())!=null){ System.out.println(socket.getRemoteSocketAddress()+":Said:"+msg); } } catch (IOException e) { e.printStackTrace(); } } }
- How to realize multiple sending and multiple receiving this time
The client sends messages repeatedly using a loop.
The server receives messages repeatedly using a loop. - Now why can't the server receive messages from multiple clients at the same time.
At present, the server is single threaded and can only process messages from one client at a time.
##TCP communication - accept multiple client messages at the same time
1. Can our previous communication communicate with multiple clients at the same time? Why?
No
A single thread can only handle Socket communication of one client at a time
2. How can the server handle the communication needs of multiple clients?
Introduce multithreading.
package com.itheima.d8_socket3; import java.io.IOException; import java.io.OutputStream; import java.io.PrintStream; import java.net.Socket; import java.util.Scanner; /** * Objective: to realize that the server can process multiple client messages at the same time */ public class ClientDemo1 { public static void main(String[] args){ try { System.out.println("==============Client started successfully==================="); //1. Create a Socket communication pipeline to request the connection of the server //public Socket(String host , int port) //Parameter 1: Ip address of the server parameter 2: port of the server Socket socket=new Socket("127.0.0.1",8888); //2. Get a byte output stream from the socket communication pipeline, which is responsible for sending data OutputStream os=socket.getOutputStream(); //3. Package the low-level byte stream into a print stream PrintStream ps=new PrintStream(os); Scanner sc=new Scanner(System.in); while(true){ System.out.println("Please"); String msg= sc.nextLine(); //4. Send message ps.println(msg); ps.flush(); } //close resource //socket.close(); } catch (IOException e) { e.printStackTrace(); } } }
package com.itheima.d8_socket3; import java.net.ServerSocket; import java.net.Socket; /** * Objective: to develop a server for Socket network programming entry code to accept messages */ public class ServerDemo2 { public static void main(String[] args) { try { System.out.println("==============The server is started successfully==================="); //1. Registered port ServerSocket serverSocket = new ServerSocket(8888); //a. Define an endless loop. The main thread is responsible for continuously receiving the Socket pipe connection of the client. while (true) { //2. After receiving a Socket pipe from a client, an independent sub thread is responsible for reading the message Socket socket = serverSocket.accept(); System.out.println(socket.getRemoteSocketAddress()+"He's here! He's online!"); //3. Start creating independent thread processing socket new ServerReaderThread(socket).start(); } } catch (Exception e) { e.printStackTrace(); } } }
package com.itheima.d8_socket3; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.net.Socket; public class ServerReaderThread extends Thread{ private Socket socket; public ServerReaderThread(Socket socket) { this.socket = socket; } @Override public void run() { try { //3. Get a byte input stream from the socket communication pipeline InputStream is = socket.getInputStream(); //4. Wrap the byte input stream into a buffered character input stream for message reception BufferedReader br = new BufferedReader(new InputStreamReader(is)); //5. Read the message by line String msg; while ((msg = br.readLine()) != null) { System.out.println(socket.getRemoteSocketAddress() + ":Said:" + msg); } } catch (Exception e) { e.printStackTrace(); System.out.println(socket.getRemoteSocketAddress()+"Offline"); } } }
- This is how to realize the server to receive messages from multiple clients.
The main thread defines a loop that is responsible for receiving the Socket pipe connection of the client
After receiving a Socket communication pipeline, an independent thread is assigned to handle it.
##TCP communication - using thread pool optimization
1. What are the problems with the current communication architecture?
The thread model of client and server is N-N relationship.
The more concurrent clients, the faster the system crashes.
package com.itheima.d9_socket4; import java.io.IOException; import java.io.OutputStream; import java.io.PrintStream; import java.net.Socket; import java.util.Scanner; /** * Objective: to realize that the server can process multiple client messages at the same time */ public class ClientDemo1 { public static void main(String[] args){ try { System.out.println("==============Client started successfully==================="); //1. Create a Socket communication pipeline to request the connection of the server //public Socket(String host , int port) //Parameter 1: Ip address of the server parameter 2: port of the server Socket socket=new Socket("127.0.0.1",6666); //2. Get a byte output stream from the socket communication pipeline, which is responsible for sending data OutputStream os=socket.getOutputStream(); //3. Package the low-level byte stream into a print stream PrintStream ps=new PrintStream(os); Scanner sc=new Scanner(System.in); while(true){ System.out.println("Please"); String msg= sc.nextLine(); //4. Send message ps.println(msg); ps.flush(); } //close resource //socket.close(); } catch (IOException e) { e.printStackTrace(); } } }
package com.itheima.d9_socket4; import com.itheima.d8_socket3.ServerReaderThread; import java.net.ServerSocket; import java.net.Socket; import java.util.concurrent.*; /** * Goal: use thread pool optimization to realize communication. */ public class ServerDemo2 { //Use static variables to remember a thread pool object private static ExecutorService pool=new ThreadPoolExecutor(3, 5, 6, TimeUnit.SECONDS, new ArrayBlockingQueue<>(2), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy()); public static void main(String[] args) { try { System.out.println("==============The server is started successfully==================="); //1. Registered port ServerSocket serverSocket = new ServerSocket(6666); //a. Define an endless loop. The main thread is responsible for continuously receiving the Socket pipe connection of the client. while (true) { //2. Receive the Socket pipe of each client Socket socket = serverSocket.accept(); System.out.println(socket.getRemoteSocketAddress()+"He's here! He's online!"); //The task object is responsible for reading messages Runnable target=new ServerReaderRunnable(socket); pool.execute(target); } } catch (Exception e) { e.printStackTrace(); } } }
package com.itheima.d9_socket4; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.net.Socket; public class ServerReaderRunnable implements Runnable{ private Socket socket; public ServerReaderRunnable(Socket socket){ this.socket=socket; } @Override public void run() { try { //3. Get a byte input stream from the socket communication pipeline InputStream is = socket.getInputStream(); //4. Wrap the byte input stream into a buffered character input stream for message reception BufferedReader br = new BufferedReader(new InputStreamReader(is)); //5. Read the message by line String msg; while ((msg = br.readLine()) != null) { System.out.println(socket.getRemoteSocketAddress() + ":Said:" + msg); } } catch (Exception e) { e.printStackTrace(); System.out.println(socket.getRemoteSocketAddress()+"Offline"); } } }
- What are the advantages of using thread pool this time?
The server can reuse threads to process multiple clients, which can avoid system paralysis.
It is suitable for scenarios where the communication time of the client is short.
##TCP communication case - instant messaging
1. What is the meaning of instant messaging and how to design it?
Instant messaging refers to that messages sent by one client can be received by other clients.
Before, our messages were sent to the server.
Instant messaging needs the design idea of port forwarding.
- What is the meaning of instant messaging and how to design it?
- Instant messaging refers to that messages sent by one client can be received by other clients
- Instant messaging needs the design idea of port forwarding.
- The server needs to store the online Socket pipeline
- Once a message is received, it is pushed to other channels
package com.itheima.d10_socket5_sms; import java.io.*; import java.net.Socket; import java.util.Scanner; /** * Objectives: * 1.Send message to client * 2.The client may need to receive a message at any time */ public class ClientDemo1 { public static void main(String[] args){ try { System.out.println("==============Client started successfully==================="); //1. Create a Socket communication pipeline to request the connection of the server //public Socket(String host , int port) //Parameter 1: Ip address of the server parameter 2: port of the server Socket socket=new Socket("127.0.0.1",6666); //Create an independent thread dedicated to reading messages from this client (the server may forward messages at any time) new ClientReaderThread(socket).start(); //2. Get a byte output stream from the socket communication pipeline, which is responsible for sending data OutputStream os=socket.getOutputStream(); //3. Package the low-level byte stream into a print stream PrintStream ps=new PrintStream(os); Scanner sc=new Scanner(System.in); while(true){ System.out.println("Please"); String msg= sc.nextLine(); //4. Send message ps.println(msg); ps.flush(); } //close resource //socket.close(); } catch (IOException e) { e.printStackTrace(); } } } class ClientReaderThread extends Thread{ private Socket socket; public ClientReaderThread(Socket socket) { this.socket = socket; } @Override public void run() { try { //3. Get a byte input stream from the socket communication pipeline InputStream is = socket.getInputStream(); //4. Wrap the byte input stream into a buffered character input stream for message reception BufferedReader br = new BufferedReader(new InputStreamReader(is)); //5. Read the message by line String msg; while ((msg = br.readLine()) != null) { System.out.println( "Message received:" + msg); } } catch (Exception e) { e.printStackTrace(); System.out.println(socket.getRemoteSocketAddress()+"The server kicked you out"); } } }
package com.itheima.d10_socket5_sms; import com.itheima.d8_socket3.ServerReaderThread; import com.itheima.d9_socket4.ServerReaderRunnable; import java.io.*; import java.net.ServerSocket; import java.net.Socket; import java.util.ArrayList; import java.util.List; import java.util.concurrent.*; /** * Objectives: */ public class ServerDemo2 { //Define a static List collection to store all currently online socket pipes public static List<Socket> allOnlineSockets=new ArrayList<>(); public static void main(String[] args) { try { System.out.println("==============The server is started successfully==================="); //1. Registered port ServerSocket serverSocket = new ServerSocket(6666); //a. Define an endless loop. The main thread is responsible for continuously receiving the Socket pipe connection of the client. while (true) { //2. Receive the Socket pipe of each client Socket socket = serverSocket.accept(); System.out.println(socket.getRemoteSocketAddress()+"He's here! He's online!"); allOnlineSockets.add(socket);//Online completion //3. Create an independent thread to handle the socket pipe separately new ServerReaderThread(socket).start(); } } catch (Exception e) { e.printStackTrace(); } } }
package com.itheima.d10_socket5_sms; import java.io.*; import java.net.Socket; public class ServerReaderThread extends Thread{ private Socket socket; public ServerReaderThread(Socket socket) { this.socket = socket; } @Override public void run() { try { //3. Get a byte input stream from the socket communication pipeline InputStream is = socket.getInputStream(); //4. Wrap the byte input stream into a buffered character input stream for message reception BufferedReader br = new BufferedReader(new InputStreamReader(is)); //5. Read the message by line String msg; while ((msg = br.readLine()) != null) { System.out.println(socket.getRemoteSocketAddress() + ":Said:" + msg); //Forward this message to all client socket pipes through the port sendMsgToAll(msg); } } catch (Exception e) { e.printStackTrace(); System.out.println(socket.getRemoteSocketAddress()+"Offline"); ServerDemo2.allOnlineSockets.remove(socket); } } private void sendMsgToAll(String msg) throws IOException { for (Socket socket : ServerDemo2.allOnlineSockets) { PrintStream ps=new PrintStream(socket.getOutputStream()); ps.println(msg); ps.flush(); } } }
chat
package com.itheima.d11_chat; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.DataInputStream; import java.io.DataOutputStream; import java.net.Socket; /** * @Author xlei(Xu Lei) * Client interface */ public class ClientChat implements ActionListener { /** 1.Design interface */ private JFrame win = new JFrame(); /** 2.Message content framework */ public JTextArea smsContent =new JTextArea(23 , 50); /** 3.Send message box */ private JTextArea smsSend = new JTextArea(4,40); /** 4.Area of online population */ /** Depositor's data */ /** Window showing the number of people online */ public JList<String> onLineUsers = new JList<>(); // Private chat button private JCheckBox isPrivateBn = new JCheckBox("Private chat"); // Message button private JButton sendBn = new JButton("send out"); // Login interface private JFrame loginView; private JTextField ipEt , nameEt , idEt; private Socket socket ; public static void main(String[] args) { new ClientChat().initView(); } private void initView() { /** Initialize the interface of the chat window */ win.setSize(650, 600); /** Show login interface */ displayLoginView(); /** Show chat interface */ //displayChatView(); } private void displayChatView() { JPanel bottomPanel = new JPanel(new BorderLayout()); //----------------------------------------------- // Add message boxes and buttons to the bottom of the window win.add(bottomPanel, BorderLayout.SOUTH); bottomPanel.add(smsSend); JPanel btns = new JPanel(new FlowLayout(FlowLayout.LEFT)); btns.add(sendBn); btns.add(isPrivateBn); bottomPanel.add(btns, BorderLayout.EAST); //----------------------------------------------- // Bind click event listener to send message button // Add the display message area centerPanel to the middle of the window smsContent.setBackground(new Color(0xdd,0xdd,0xdd)); // Allow the display message area to scroll. win.add(new JScrollPane(smsContent), BorderLayout.CENTER); smsContent.setEditable(false); //----------------------------------------------- // User list and private chat are placed on the far right of the window Box rightBox = new Box(BoxLayout.Y_AXIS); onLineUsers.setFixedCellWidth(120); onLineUsers.setVisibleRowCount(13); rightBox.add(new JScrollPane(onLineUsers)); win.add(rightBox, BorderLayout.EAST); //----------------------------------------------- // Close the window and exit the current program win.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); win.pack(); // swing plus this sentence can have the function of closing the window /** Set the window to center and display */ setWindowCenter(win,650,600,true); // Send button binding click event sendBn.addActionListener(this); } private void displayLoginView(){ /** Let the user log in first * Server ip * user name * id * */ /** Display a qq login box */ loginView = new JFrame("Sign in"); loginView.setLayout(new GridLayout(3, 1)); loginView.setSize(400, 230); JPanel ip = new JPanel(); JLabel label = new JLabel(" IP:"); ip.add(label); ipEt = new JTextField(20); ip.add(ipEt); loginView.add(ip); JPanel name = new JPanel(); JLabel label1 = new JLabel("full name:"); name.add(label1); nameEt = new JTextField(20); name.add(nameEt); loginView.add(name); JPanel btnView = new JPanel(); JButton login = new JButton("land"); btnView.add(login); JButton cancle = new JButton("cancel"); btnView.add(cancle); loginView.add(btnView); // Close the window and exit the current program loginView.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setWindowCenter(loginView,400,260,true); /** Click events for login and unbind */ login.addActionListener(this); cancle.addActionListener(this); } private static void setWindowCenter(JFrame frame, int width , int height, boolean flag) { /** Get the width and height of the screen where the system is located */ Dimension ds = frame.getToolkit().getScreenSize(); /** Get the width of the computer */ int width1 = ds.width; /** high */ int height1 = ds.height ; System.out.println(width1 +"*" + height1); /** Set the coordinates of the upper left corner of the window */ frame.setLocation(width1/2 - width/2, height1/2 -height/2); frame.setVisible(flag); } @Override public void actionPerformed(ActionEvent e) { /** Get the event source of the click */ JButton btn = (JButton) e.getSource(); switch(btn.getText()){ case "land": String ip = ipEt.getText().toString(); String name = nameEt.getText().toString(); // Check whether the parameter is empty // Error prompt String msg = "" ; // 12.1.2.0 // \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\ if(ip==null || !ip.matches("\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}")){ msg = "Please enter a legal server ip address"; }else if(name==null || !name.matches("\\S{1,}")){ msg = "Name must be more than 1 character"; } if(!msg.equals("")){ /** msg If there is content description, the parameter is empty */ // Parameter 1: which window will pop up and put it in JOptionPane.showMessageDialog(loginView, msg); }else{ try { // The parameters are legal // The currently logged in user logs in to the server /** First display the name of the current user to the interface */ win.setTitle(name); // Log in to the server and connect a socket pipe socket = new Socket(ip, Constants.PORT); //Allocate a thread for the socket of the client to receive messages new ClientReader(this,socket).start(); // Bring the user information DataOutputStream dos = new DataOutputStream(socket.getOutputStream()); dos.writeInt(1); // logon message dos.writeUTF(name.trim()); dos.flush(); // The chat interface pops up in the current relationship window loginView.dispose(); // Login window destroyed displayChatView(); // Shows the chat window } catch (Exception e1) { e1.printStackTrace(); } } break; case "cancel": /** Exit the system */ System.exit(0); break; case "send out": // Get the content of the sent message String msgSend = smsSend.getText().toString(); if(!msgSend.trim().equals("")){ /** Send a message to the server */ try { // Determine whether to send messages to whom String selectName = onLineUsers.getSelectedValue(); int flag = 2 ;// Mass @ messages if(selectName!=null&&!selectName.equals("")){ msgSend =("@"+selectName+","+msgSend); /** Judge whether private law is selected */ if(isPrivateBn.isSelected()){ /** private law */ flag = 3 ;//Private message } } DataOutputStream dos = new DataOutputStream(socket.getOutputStream()); dos.writeInt(flag); // Mass messaging to everyone dos.writeUTF(msgSend); if(flag == 3){ // Tell the server who I sent it to dos.writeUTF(selectName.trim()); } dos.flush(); } catch (Exception e1) { e1.printStackTrace(); } } smsSend.setText(null); break; } } } class ClientReader extends Thread { private Socket socket; private ClientChat clientChat ; public ClientReader(ClientChat clientChat, Socket socket) { this.clientChat = clientChat; this.socket = socket; } @Override public void run() { try { DataInputStream dis = new DataInputStream(socket.getInputStream()); /** The loop has been waiting for messages from the client */ while(true){ /** Read the current message type: login, mass sending, private chat, @ message */ int flag = dis.readInt(); if(flag == 1){ // The number of people online is back String nameDatas = dis.readUTF(); // Interface showing the number of people online String[] names = nameDatas.split(Constants.SPILIT); clientChat.onLineUsers.setListData(names); }else if(flag == 2){ // Mass messaging String msg = dis.readUTF() ; clientChat.smsContent.append(msg); //Scroll to bottom clientChat.smsContent.setCaretPosition(clientChat.smsContent.getText().length()); } } } catch (Exception e) { e.printStackTrace(); } } }
package com.itheima.d11_chat; public class Constants { /** constant */ public static final int PORT = 7778 ; /** Protocol separator */ public static final String SPILIT = "003197♣♣㏘♣④④♣"; }
package com.itheima.d11_chat; import java.io.DataInputStream; import java.io.DataOutputStream; import java.net.ServerSocket; import java.net.Socket; import java.text.SimpleDateFormat; import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.Set; /** * @Author * @Email dlei0009@163.com */ public class ServerChat { /** Define a collection to store all online socket s */ public static Map<Socket, String> onLineSockets = new HashMap<>(); public static void main(String[] args) { try { /** Register port */ ServerSocket serverSocket = new ServerSocket(Constants.PORT); /** The loop keeps waiting for all possible client connections */ while(true){ Socket socket = serverSocket.accept(); /** Configure a separate thread to handle the socket pipeline of the client */ new ServerReader(socket).start(); } } catch (Exception e) { e.printStackTrace(); } } } class ServerReader extends Thread { private Socket socket; public ServerReader(Socket socket) { this.socket = socket; } @Override public void run() { DataInputStream dis = null; try { dis = new DataInputStream(socket.getInputStream()); /** The loop has been waiting for messages from the client */ while(true){ /** Read the current message type: login, mass sending, private chat, @ message */ int flag = dis.readInt(); if(flag == 1){ /** First save the currently logged in client socket to the socket set of the number of online people */ String name = dis.readUTF() ; System.out.println(name+"---->"+socket.getRemoteSocketAddress()); ServerChat.onLineSockets.put(socket, name); } writeMsg(flag,dis); } } catch (Exception e) { System.out.println("--Someone's offline--"); // Move the current socket from the number of people online ServerChat.onLineSockets.remove(socket); try { // Update the number of people online and send it to all clients writeMsg(1,dis); } catch (Exception e1) { e1.printStackTrace(); } } } private void writeMsg(int flag, DataInputStream dis) throws Exception { // DataOutputStream dos = new DataOutputStream(socket.getOutputStream()); // Define a variable to store the final message form String msg = null ; if(flag == 1){ /** Read all online numbers and send them to all clients to update their online number list */ /** onlineNames = [Xu Lei, zhangsan, Li Gang]*/ StringBuilder rs = new StringBuilder(); Collection<String> onlineNames = ServerChat.onLineSockets.values(); // Determine whether there are online people if(onlineNames != null && onlineNames.size() > 0){ for(String name : onlineNames){ rs.append(name+ Constants.SPILIT); } // Xu Lei 003197 ♣♣ ㏘ ♣ ④④ ♣ zhangsan003197 ♣♣ ㏘ ♣ ④④ ♣ Li Gang 003197 ♣♣ ㏘ ♣ ④④ ♣ // Remove the last separator msg = rs.substring(0, rs.lastIndexOf(Constants.SPILIT)); /** Send messages to all clients */ sendMsgToAll(flag,msg); } }else if(flag == 2 || flag == 3){ // Read a mass message or @ message String newMsg = dis.readUTF() ; // news // Get sender String sendName = ServerChat.onLineSockets.get(socket); // Li Gang time // Content-- StringBuilder msgFinal = new StringBuilder(); // time SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss EEE"); if(flag == 2){ msgFinal.append(sendName).append(" ").append(sdf.format(System.currentTimeMillis())).append("\r\n"); msgFinal.append(" ").append(newMsg).append("\r\n"); sendMsgToAll(flag,msgFinal.toString()); }else if(flag == 3){ msgFinal.append(sendName).append(" ").append(sdf.format(System.currentTimeMillis())).append("Send it to you privately\r\n"); msgFinal.append(" ").append(newMsg).append("\r\n"); // Private hair // To whom String destName = dis.readUTF(); sendMsgToOne(destName,msgFinal.toString()); } } } /** * @param destName To whom * @param msg Message content sent * @throws Exception */ private void sendMsgToOne(String destName, String msg) throws Exception { // Get all the online socket pipes and write messages to these pipes Set<Socket> allOnLineSockets = ServerChat.onLineSockets.keySet(); for(Socket sk : allOnLineSockets){ // Get the socket that needs to be sent privately // Send private messages only to the socket corresponding to this name if(ServerChat.onLineSockets.get(sk).trim().equals(destName)){ DataOutputStream dos = new DataOutputStream(sk.getOutputStream()); dos.writeInt(2); // Message type dos.writeUTF(msg); dos.flush(); } } } private void sendMsgToAll(int flag, String msg) throws Exception { // Get all the online socket pipes and write messages to these pipes Set<Socket> allOnLineSockets = ServerChat.onLineSockets.keySet(); for(Socket sk : allOnLineSockets){ DataOutputStream dos = new DataOutputStream(sk.getOutputStream()); dos.writeInt(flag); // Message type dos.writeUTF(msg); dos.flush(); } } }
package com.itheima.d11_chat; public class User { private Integer id ; private String name ; public User(Integer id, String name) { this.id = id; this.name = name; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "User [id=" + id + ", name=" + name + "]"; } }
##TCP communication practice case - simulated BS system
1. What were the previous clients like
In fact, it is the CS architecture. The client needs to be developed and implemented by ourselves.
2. What is the BS structure? Do you need to develop the client?
The browser accesses the server without developing the client.
- How does TCP communication realize that BS requests web page information back?
- The client uses the browser to initiate the request (there is no need to develop the client)
- The server must respond to the data according to the protocol rules of the browser.
- What protocol rules do browsers use?
- HTTP protocol (simple understanding)
package com.itheima.d12_bs; import java.io.PrintStream; import java.net.ServerSocket; import java.net.Socket; import java.util.concurrent.*; /** Understanding: basic understanding of BS browser server. introduce: Before, both the client and server needed to be developed by themselves. That is, CS architecture. Next, simulate the BS architecture. Client: browser. (no development required) Server side: self-developed. Requirements: request this program in the browser and respond to a web page text to be displayed to the browser */ public class BSserverDemo { // Use static variables to remember a thread pool object private static ExecutorService pool = new ThreadPoolExecutor(300, 1500, 6, TimeUnit.SECONDS, new ArrayBlockingQueue<>(2) , Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy()); public static void main(String[] args) { try { // 1. Registered port ServerSocket ss = new ServerSocket(8080); // 2. Create a loop to receive requests from multiple clients. while(true){ //Create links with browsers Socket socket = ss.accept(); // 3. Give it to an independent thread for processing! pool.execute(new ServerReaderRunnable(socket)); } } catch (Exception e) { e.printStackTrace(); } } }
package com.itheima.d12_bs; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.io.PrintStream; import java.net.Socket; public class ServerReaderRunnable implements Runnable{ private Socket socket; public ServerReaderRunnable(Socket socket){ this.socket = socket; } @Override public void run() { try { // The browser has established a Socket pipeline with this thread // The response message is displayed to the browser PrintStream ps = new PrintStream(socket.getOutputStream()); // You must respond to the data in HTTP protocol format, otherwise the browser will not recognize the message ps.println("HTTP/1.1 200 OK"); // The protocol type and version respond successfully! ps.println("Content-Type:text/html;charset=UTF-8"); // Data type of response: text / Web page ps.println(); // A blank line must be sent // Before you can respond to the data back to the browser ps.println("<span style='color:red;font-size:90px'><The best 149 </span>"); ps.close(); } catch (Exception e) { System.out.println(socket.getRemoteSocketAddress() + "Offline!!!"); } } }
. That is, CS architecture.
Next, simulate the BS architecture.
Client: browser. (no development required) Server side: self-developed. Requirements: request this program in the browser and respond to a web page text to be displayed to the browser
*/
public class BSserverDemo {
//Remember that a thread uses a static variable pool
private static ExecutorService pool = new ThreadPoolExecutor(300,
1500, 6, TimeUnit.SECONDS,
new ArrayBlockingQueue<>(2)
, Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());
public static void main(String[] args) { try { // 1. Registered port ServerSocket ss = new ServerSocket(8080); // 2. Create a loop to receive requests from multiple clients. while(true){ //Create links with browsers Socket socket = ss.accept(); // 3. Give it to an independent thread for processing! pool.execute(new ServerReaderRunnable(socket)); } } catch (Exception e) { e.printStackTrace(); } }
}
```java package com.itheima.d12_bs; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.io.PrintStream; import java.net.Socket; public class ServerReaderRunnable implements Runnable{ private Socket socket; public ServerReaderRunnable(Socket socket){ this.socket = socket; } @Override public void run() { try { // The browser has established a Socket pipeline with this thread // The response message is displayed to the browser PrintStream ps = new PrintStream(socket.getOutputStream()); // You must respond to the data in HTTP protocol format, otherwise the browser will not recognize the message ps.println("HTTP/1.1 200 OK"); // The protocol type and version respond successfully! ps.println("Content-Type:text/html;charset=UTF-8"); // Data type of response: text / Web page ps.println(); // A blank line must be sent // Before you can respond to the data back to the browser ps.println("<span style='color:red;font-size:90px'><The best 149 </span>"); ps.close(); } catch (Exception e) { System.out.println(socket.getRemoteSocketAddress() + "Offline!!!"); } } }