Java: network programming

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

  1. 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
  2. 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

nameexplain
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
  1. Who is the representative class of IP address?
    InetAddress class
  2. How to get native IP objects
    public static InetAddress getLocalHost()
  3. 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.
  1. What is the function of port number?
    Uniquely identifies the process (program) running on the computer device
  2. 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 modelCorresponding to each layerOperation Oriented
application layerapplication layerHTTP,FTP,DNS,SMTP...Applications need to pay attention to: browser, mailbox. Programmers usually develop at this level
Presentation layer
Session layer
Transport layerTransport layerTCP,UDP...Select the TCP and UDP protocols to use
network layernetwork layerIP,ICMP...Encapsulate the source and target IP for path selection
data link layerData link layer + physicalPhysical addressing, bitstreamTransmission 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

methodexplain
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

methodexplain
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();
    }
}

  1. 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
  2. What is the packet object?
    • DatagramPacket
  3. 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);
        }
    }
}


  1. 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);
        }
    }
}


  1. 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.
  2. 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

methodexplain
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();
        }

    }
}

  1. Who is the representative class of TCP communication client?
    • Socket class
    • public Socket(String host , int port)
  2. 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

methodexplain
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();
        }

    }
}


  1. 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.
  2. 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.

  1. 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();
        }

    }
}

  1. 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.
  2. 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");
        }

        }
    }


  1. 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");
        }
    }
}
  1. 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.

  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
    • 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.

  1. 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!!!");
        }
    }
}

Tags: Java network Network Protocol udp programming language

Posted by rex9990 on Tue, 17 May 2022 01:52:38 +0300